# HG changeset patch # User Mathieu Lacage # Date 1204147179 -3600 # Node ID e667dc0f350e2e13afa434068d0184edec56e4ae # Parent d64b1561b1c25cba03252c1156e6950d1584b23f# Parent 50d0da37f02f80090d3fbffeba02eb2559b252f9 merge with HEAD diff -r d64b1561b1c2 -r e667dc0f350e examples/csma-broadcast.cc --- a/examples/csma-broadcast.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/csma-broadcast.cc Wed Feb 27 22:19:39 2008 +0100 @@ -154,30 +154,36 @@ // Create the OnOff application to send UDP datagrams of size // 512 bytes (default) at a rate of 500 Kb/s (default) from n0 NS_LOG_INFO ("Create Applications."); - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("255.255.255.255", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("255.255.255.255", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.0)); ooff->Stop (Seconds(10.0)); // Create an optional packet sink to receive these packets - Ptr sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ( + "Node", n1, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); sink->Stop (Seconds (10.0)); // Create an optional packet sink to receive these packets - sink = CreateObject ( - n2, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + sink = CreateObjectWith ( + "Node", n2, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n2->AddApplication (sink); + // Start the sink sink->Start (Seconds (1.0)); sink->Stop (Seconds (10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/csma-multicast.cc --- a/examples/csma-multicast.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/csma-multicast.cc Wed Feb 27 22:19:39 2008 +0100 @@ -52,6 +52,7 @@ #include "ns3/ipv4-route.h" #include "ns3/onoff-application.h" #include "ns3/packet-sink.h" +#include "ns3/uinteger.h" using namespace ns3; @@ -281,14 +282,16 @@ // Configure a multicast packet generator that generates a packet // every few seconds - Ptr ooff = CreateObject ( - n0, - InetSocketAddress (multicastGroup, port), - "Udp", - ConstantVariable(1), - ConstantVariable(0), - DataRate ("255b/s"), - 128); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress (multicastGroup, port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0), + "DataRate", DataRate ("255b/s"), + "PacketSize", Uinteger (128)); + n0->AddApplication (ooff); // // Tell the application when to start and stop. // @@ -298,10 +301,12 @@ // Create an optional packet sink to receive these packets // If you enable logging on this (above) it will print a log statement // for every packet received - Ptr sink = CreateObject ( - n4, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ( + "Node", n4, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n4->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); sink->Stop (Seconds (10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/csma-one-subnet.cc --- a/examples/csma-one-subnet.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/csma-one-subnet.cc Wed Feb 27 22:19:39 2008 +0100 @@ -165,12 +165,15 @@ // NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.1.2", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.1.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); + // // Tell the application when to start and stop. // @@ -179,12 +182,13 @@ // // Create a similar flow from n3 to n0, starting at time 1.1 seconds // - ooff = CreateObject ( - n3, - InetSocketAddress ("10.1.1.1", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + ooff = CreateObjectWith ( + "Node", n3, + "Remote", Address (InetSocketAddress ("10.1.1.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n3->AddApplication (ooff); ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/csma-packet-socket.cc --- a/examples/csma-packet-socket.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/csma-packet-socket.cc Wed Feb 27 22:19:39 2008 +0100 @@ -38,6 +38,7 @@ #include "ns3/ptr.h" #include "ns3/random-variable.h" #include "ns3/log.h" +#include "ns3/string.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -61,7 +62,10 @@ static Ptr CreateCsmaDevice (Ptr node, Ptr channel) { - Ptr device = CreateObject (node); + Ptr device = CreateObjectWith ("Node", node, + "Address", Mac48Address::Allocate (), + "EncapsulationMode", String ("Llc")); + node->AddDevice (device); device->Attach (channel); Ptr queue = Queue::CreateDefault (); device->AddQueue (queue); @@ -134,23 +138,26 @@ // 210 bytes at a rate of 448 Kb/s // from n0 to n1 NS_LOG_INFO ("Create Applications."); - Ptr ooff = CreateObject ( - n0, - n0ToN1, - "Packet", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (n0ToN1), + "Protocol", TypeId::LookupByName ("Packet"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.0)); ooff->Stop (Seconds(10.0)); // Create a similar flow from n3 to n0, starting at time 1.1 seconds - ooff = CreateObject ( - n3, - n3ToN0, - "Packet", - ConstantVariable(1), - ConstantVariable(0)); + ooff = CreateObjectWith ( + "Node", n3, + "Remote", Address (n3ToN0), + "Protocol", TypeId::LookupByName ("Packet"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n3->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/mixed-global-routing.cc --- a/examples/mixed-global-routing.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/mixed-global-routing.cc Wed Feb 27 22:19:39 2008 +0100 @@ -42,6 +42,7 @@ #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/config.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -65,6 +66,7 @@ #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/global-route-manager.h" +#include "ns3/uinteger.h" using namespace ns3; @@ -110,10 +112,8 @@ // topology code DefaultValue::Bind ("Queue", "DropTailQueue"); - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); - - //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30); + Config::SetDefault ("OnOffApplication::PacketSize", Uinteger (210)); + Config::SetDefault ("OnOffApplication::DataRate", DataRate ("448kb/s")); // Allow the user to override any of the defaults and the above // Bind ()s at run-time, via command-line arguments @@ -191,14 +191,16 @@ // 210 bytes at a rate of 448 Kb/s NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.3.2", port), - "Udp", - ConstantVariable (1), - ConstantVariable (0), - DataRate("300bps"), - 50); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.3.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable (1), + "OffTime", ConstantVariable (0), + "DataRate", DataRate("300bps"), + "PacketSize", Uinteger (50)); + n0->AddApplication (ooff); // Start the application ooff->Start (Seconds (1.0)); ooff->Stop (Seconds (10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/simple-alternate-routing.cc --- a/examples/simple-alternate-routing.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/simple-alternate-routing.cc Wed Feb 27 22:19:39 2008 +0100 @@ -43,6 +43,8 @@ #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/config.h" +#include "ns3/uinteger.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -105,8 +107,8 @@ // instantiate, when the queue factory is invoked in the topology code DefaultValue::Bind ("Queue", "DropTailQueue"); - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "300b/s"); + Config::SetDefault ("OnOffApplication::PacketSize", Uinteger (210)); + Config::SetDefault ("OnOffApplication::DataRate", DataRate ("300b/s")); // The below metric, if set to 3 or higher, will cause packets between // n1 and n3 to take the 2-hop route through n2 @@ -182,21 +184,25 @@ uint16_t port = 9; // Discard port (RFC 863) // Create a flow from n3 to n1, starting at time 1.1 seconds - Ptr ooff = CreateObject ( - n3, - InetSocketAddress ("10.1.1.1", port), - "Udp", - ConstantVariable (1), - ConstantVariable (0)); + Ptr ooff = + CreateObjectWith ( + "Node", n3, + "Remote", Address (InetSocketAddress ("10.1.1.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable (1), + "OffTime", ConstantVariable (0)); + n3->AddApplication (ooff); // Start the application ooff->Start (Seconds (1.1)); ooff->Stop (Seconds (10.0)); // Create a packet sink to receive these packets - Ptr sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ( + "Node", n1, + "Remote", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.1)); sink->Stop (Seconds (10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/simple-error-model.cc --- a/examples/simple-error-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/simple-error-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -43,6 +43,9 @@ #include "ns3/command-line.h" #include "ns3/default-value.h" #include "ns3/ptr.h" +#include "ns3/config.h" +#include "ns3/uinteger.h" +#include "ns3/string.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -64,6 +67,7 @@ #include "ns3/onoff-application.h" #include "ns3/packet-sink.h" #include "ns3/error-model.h" +#include "ns3/double.h" using namespace ns3; @@ -78,15 +82,12 @@ LogComponentEnable ("SimplePointToPointExample", LOG_LEVEL_INFO); #endif - // Set up some default values for the simulation. Use the Bind() - // technique to tell the system what subclass of ErrorModel to use - DefaultValue::Bind ("ErrorModel", "RateErrorModel"); // Set a few parameters - DefaultValue::Bind ("RateErrorModelErrorRate", "0.01"); - DefaultValue::Bind ("RateErrorModelErrorUnit", "EU_PKT"); - - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); + Config::SetDefault ("RateErrorModel::ErrorRate", Double (0.01)); + Config::SetDefault ("RateErrorModel::ErrorUnit", String ("EU_PKT")); + + Config::SetDefault ("OnOffApplication::PacketSize", Uinteger (210)); + Config::SetDefault ("OnOffApplication::DataRate", DataRate ("448kb/s")); // Allow the user to override any of the defaults and the above @@ -142,41 +143,46 @@ // 210 bytes at a rate of 448 Kb/s NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.3.2", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.3.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.0)); ooff->Stop (Seconds(10.0)); // Create an optional packet sink to receive these packets - Ptr sink = CreateObject ( - n3, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = CreateObjectWith ( + "Node", n3, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n3->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); sink->Stop (Seconds (10.0)); // Create a similar flow from n3 to n1, starting at time 1.1 seconds - ooff = CreateObject ( - n3, - InetSocketAddress ("10.1.2.1", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + ooff = CreateObjectWith ( + "Node", n3, + "Remote", Address (InetSocketAddress ("10.1.2.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n3->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); // Create a packet sink to receive these packets - sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + sink = CreateObjectWith ( + "Node", n1, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.1)); sink->Stop (Seconds (10.0)); @@ -200,16 +206,8 @@ (n3, channel2); // Create an ErrorModel based on the implementation (constructor) // specified by the default classId - Ptr em = ErrorModel::CreateDefault (); - NS_ASSERT (em != 0); - // Now, query interface on the resulting em pointer to see if a - // RateErrorModel interface exists. If so, set the packet error rate - Ptr bem = em->GetObject (); - if (bem) - { - bem->SetRandomVariable (UniformVariable ()); - bem->SetRate (0.001); - } + Ptr em = CreateObjectWith ("RanVar", UniformVariable (0.0, 1.0), + "Rate", Double (0.001)); nd3->AddReceiveErrorModel (em); // Now, let's use the ListErrorModel and explicitly force a loss diff -r d64b1561b1c2 -r e667dc0f350e examples/simple-global-routing.cc --- a/examples/simple-global-routing.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/simple-global-routing.cc Wed Feb 27 22:19:39 2008 +0100 @@ -48,6 +48,8 @@ #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/config.h" +#include "ns3/uinteger.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -110,8 +112,8 @@ // instantiate, when the queue factory is invoked in the topology code DefaultValue::Bind ("Queue", "DropTailQueue"); - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); + Config::SetDefault ("OnOffApplication::PacketSize", Uinteger (210)); + Config::SetDefault ("OnOffApplication::DataRate", DataRate ("448kb/s")); //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30); @@ -163,42 +165,45 @@ // 210 bytes at a rate of 448 Kb/s NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.3.2", port), - "Udp", - ConstantVariable (1), - ConstantVariable (0)); + Ptr ooff = + CreateObjectWith ("Node", n0, + "Remote", Address (InetSocketAddress ("10.1.3.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable (1), + "OffTime", ConstantVariable (0)); + n0->AddApplication (ooff); // Start the application ooff->Start (Seconds (1.0)); ooff->Stop (Seconds (10.0)); // Create a packet sink to receive these packets // The last argument "true" disables output from the Receive callback - Ptr sink = CreateObject ( - n3, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ("Node", n3, + "Remote", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n3->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); sink->Stop (Seconds (10.0)); // Create a similar flow from n3 to n1, starting at time 1.1 seconds - ooff = CreateObject ( - n3, - InetSocketAddress ("10.1.2.1", port), - "Udp", - ConstantVariable (1), - ConstantVariable (0)); + ooff = CreateObjectWith ( + "Node", n3, + "Remote", Address (InetSocketAddress ("10.1.2.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable (1), + "OffTime", ConstantVariable (0)); + n3->AddApplication (ooff); // Start the application ooff->Start (Seconds (1.1)); ooff->Stop (Seconds (10.0)); // Create a packet sink to receive these packets - sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + sink = CreateObjectWith ("Node", n1, + "Remote", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.1)); sink->Stop (Seconds (10.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/simple-point-to-point-olsr.cc --- a/examples/simple-point-to-point-olsr.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/simple-point-to-point-olsr.cc Wed Feb 27 22:19:39 2008 +0100 @@ -43,6 +43,8 @@ #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/config.h" +#include "ns3/string.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -61,7 +63,7 @@ #include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" #include "ns3/packet-sink.h" -#include "ns3/olsr.h" +#include "ns3/olsr-helper.h" using namespace ns3; @@ -98,16 +100,10 @@ LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL); #endif - // Set up some default values for the simulation. Use the Bind() - // technique to tell the system what subclass of Queue to use, - // and what the queue limit is + // Set up some default values for the simulation. - // The below Bind command tells the queue factory which class to - // instantiate, when the queue factory is invoked in the topology code - DefaultValue::Bind ("Queue", "DropTailQueue"); - - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); + Config::SetDefault ("OnOffApplication::PacketSize", String ("210")); + Config::SetDefault ("OnOffApplication::DataRate", String ("448kb/s")); //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30); @@ -162,45 +158,52 @@ // Enable OLSR NS_LOG_INFO ("Enabling OLSR Routing."); - olsr::EnableAllNodes (); + OlsrHelper olsr; + olsr.EnableAll (); // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.4.2", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.4.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.0)); // Create an optional packet sink to receive these packets - Ptr sink = CreateObject ( - n4, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ( + "Node", n4, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n3->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); - // Create a similar flow from n4 to n1, starting at time 1.1 seconds - ooff = CreateObject ( - n4, - InetSocketAddress ("10.1.2.1", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + // Create a similar flow from n3 to n1, starting at time 1.1 seconds + ooff = CreateObjectWith ( + "Node", n4, + "Remote", Address (InetSocketAddress ("10.1.2.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n3->AddApplication (ooff); // Start the application ooff->Start (Seconds(1.1)); // Create a packet sink to receive these packets - sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + sink = CreateObjectWith ( + "Node", n1, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.1)); diff -r d64b1561b1c2 -r e667dc0f350e examples/simple-point-to-point.cc --- a/examples/simple-point-to-point.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/simple-point-to-point.cc Wed Feb 27 22:19:39 2008 +0100 @@ -43,6 +43,8 @@ #include "ns3/default-value.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" +#include "ns3/config.h" +#include "ns3/string.h" #include "ns3/simulator.h" #include "ns3/nstime.h" @@ -75,16 +77,10 @@ LogComponentEnable ("SimplePointToPointExample", LOG_LEVEL_ALL); #endif - // Set up some default values for the simulation. Use the Bind() - // technique to tell the system what subclass of Queue to use, - // and what the queue limit is + // Set up some default values for the simulation. - // The below Bind command tells the queue factory which class to - // instantiate, when the queue factory is invoked in the topology code - DefaultValue::Bind ("Queue", "DropTailQueue"); - - DefaultValue::Bind ("OnOffApplicationPacketSize", "210"); - DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s"); + Config::SetDefault ("OnOffApplication::PacketSize", String ("210")); + Config::SetDefault ("OnOffApplication::DataRate", String ("448kb/s")); // Allow the user to override any of the defaults and the above // Bind()s at run-time, via command-line arguments @@ -139,38 +135,44 @@ // 210 bytes at a rate of 448 Kb/s NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) - Ptr ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.3.2", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + Ptr ooff = + CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.3.2", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start (Seconds(1.0)); // Create an optional packet sink to receive these packets - Ptr sink = CreateObject ( - n3, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + Ptr sink = + CreateObjectWith ( + "Node", n3, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n3->AddApplication (sink); // Start the sink sink->Start (Seconds (1.0)); // Create a similar flow from n3 to n1, starting at time 1.1 seconds - ooff = CreateObject ( - n3, - InetSocketAddress ("10.1.2.1", port), - "Udp", - ConstantVariable(1), - ConstantVariable(0)); + ooff = CreateObjectWith ( + "Node", n3, + "Remote", Address (InetSocketAddress ("10.1.2.1", port)), + "Protocol", TypeId::LookupByName ("Udp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n3->AddApplication (ooff); // Start the application ooff->Start(Seconds(1.1)); // Create a packet sink to receive these packets - sink = CreateObject ( - n1, - InetSocketAddress (Ipv4Address::GetAny (), port), - "Udp"); + sink = CreateObjectWith ( + "Node", n1, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), + "Protocol", TypeId::LookupByName ("Udp")); + n1->AddApplication (sink); // Start the sink sink->Start (Seconds (1.1)); @@ -178,21 +180,23 @@ // Create a file transfer from n0 to n3, starting at time 1.2 uint16_t servPort = 500; - ooff = CreateObject ( - n0, - InetSocketAddress ("10.1.3.2", servPort), - "Tcp", - ConstantVariable(1), - ConstantVariable(0)); + ooff = CreateObjectWith ( + "Node", n0, + "Remote", Address (InetSocketAddress ("10.1.3.2", servPort)), + "Protocol", TypeId::LookupByName ("Tcp"), + "OnTime", ConstantVariable(1), + "OffTime", ConstantVariable(0)); + n0->AddApplication (ooff); // Start the application ooff->Start (Seconds(1.2)); ooff->Stop (Seconds(1.35)); // Create a packet sink to receive these TCP packets - sink = Create ( - n3, - InetSocketAddress (Ipv4Address::GetAny (), servPort), - "Tcp"); + sink = CreateObjectWith ( + "Node", n3, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)), + "Protocol", TypeId::LookupByName ("Tcp")); + n3->AddApplication (sink); sink->Start (Seconds (1.2)); // Here, finish off packet routing configuration diff -r d64b1561b1c2 -r e667dc0f350e examples/tcp-large-transfer-errors.cc --- a/examples/tcp-large-transfer-errors.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/tcp-large-transfer-errors.cc Wed Feb 27 22:19:39 2008 +0100 @@ -196,10 +196,12 @@ localSocket->Bind (); // Create a packet sink to receive these packets - Ptr sink = Create ( - n2, - InetSocketAddress (Ipv4Address::GetAny (), servPort), - "Tcp"); + Ptr sink = + CreateObjectWith ( + "Node", n2, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)), + "Protocol", TypeId::LookupByName ("Tcp")); + n2->AddApplication (sink); sink->Start (Seconds (0.0)); sink->Stop (Seconds (10000.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/tcp-large-transfer.cc --- a/examples/tcp-large-transfer.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/tcp-large-transfer.cc Wed Feb 27 22:19:39 2008 +0100 @@ -196,10 +196,12 @@ localSocket->Bind (); // Create a packet sink to receive these packets - Ptr sink = Create ( - n2, - InetSocketAddress (Ipv4Address::GetAny (), servPort), - "Tcp"); + Ptr sink = + CreateObjectWith ( + "Node", n2, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)), + "Protocol", TypeId::LookupByName ("Tcp")); + n2->AddApplication (sink); sink->Start (Seconds (0.0)); sink->Stop (Seconds (100.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/tcp-small-transfer-oneloss.cc --- a/examples/tcp-small-transfer-oneloss.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/tcp-small-transfer-oneloss.cc Wed Feb 27 22:19:39 2008 +0100 @@ -178,10 +178,12 @@ localSocket->Bind (); // Create a packet sink to receive these packets - Ptr sink = Create ( - n2, - InetSocketAddress (Ipv4Address::GetAny (), servPort), - "Tcp"); + Ptr sink = + CreateObjectWith ( + "Node", n2, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)), + "Protocol", TypeId::LookupByName ("Tcp")); + n2->AddApplication (sink); sink->Start (Seconds (0.0)); sink->Stop (Seconds (100.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/tcp-small-transfer.cc --- a/examples/tcp-small-transfer.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/tcp-small-transfer.cc Wed Feb 27 22:19:39 2008 +0100 @@ -188,10 +188,12 @@ localSocket->Bind (); // Create a packet sink to receive these packets - Ptr sink = Create ( - n2, - InetSocketAddress (Ipv4Address::GetAny (), servPort), - "Tcp"); + Ptr sink = + CreateObjectWith ( + "Node", n2, + "Local", Address (InetSocketAddress (Ipv4Address::GetAny (), servPort)), + "Protocol", TypeId::LookupByName ("Tcp")); + n2->AddApplication (sink); sink->Start (Seconds (0.0)); sink->Stop (Seconds (100.0)); diff -r d64b1561b1c2 -r e667dc0f350e examples/udp-echo.cc --- a/examples/udp-echo.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/examples/udp-echo.cc Wed Feb 27 22:19:39 2008 +0100 @@ -47,6 +47,7 @@ #include "ns3/ipv4-route.h" #include "ns3/udp-echo-client.h" #include "ns3/udp-echo-server.h" +#include "ns3/uinteger.h" using namespace ns3; @@ -167,7 +168,9 @@ // uint16_t port = 9; // well-known echo port number - Ptr server = CreateObject (n1, port); + Ptr server = CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); // // Create a UdpEchoClient application to send UDP datagrams from node zero to // node one. @@ -176,8 +179,14 @@ uint32_t maxPacketCount = 1; Time interPacketInterval = Seconds (1.); - Ptr client = CreateObject (n0, "10.1.1.2", port, - maxPacketCount, interPacketInterval, packetSize); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (maxPacketCount), + "Interval", interPacketInterval, + "PacketSize", Uinteger (packetSize)); + n0->AddApplication (client); // // Tell the applications when to start and stop. // diff -r d64b1561b1c2 -r e667dc0f350e samples/main-adhoc-wifi.cc --- a/samples/main-adhoc-wifi.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/main-adhoc-wifi.cc Wed Feb 27 22:19:39 2008 +0100 @@ -33,6 +33,7 @@ #include "ns3/socket-factory.h" #include "ns3/command-line.h" #include "ns3/gnuplot.h" +#include "ns3/uinteger.h" #include @@ -47,6 +48,7 @@ { Ptr node = CreateObject (); Ptr device = CreateObject (node, Mac48Address (address)); + node->AddDevice (device); device->Attach (channel); Ptr mobility = CreateObject (); mobility->SetPosition (position); @@ -121,12 +123,15 @@ destination.SetProtocol (1); destination.SetSingleDevice (0); destination.SetPhysicalAddress (Mac48Address ("00:00:00:00:00:02")); - Ptr app = CreateObject (a, destination, - "Packet", - ConstantVariable (250), - ConstantVariable (0), - DataRate (60000000), - 2000); + Ptr app = + CreateObjectWith ("Node", a, + "Remote", Address (destination), + "Protocol", TypeId::LookupByName ("Packet"), + "OnTime", ConstantVariable (250), + "OffTime", ConstantVariable (0), + "DataRate", DataRate (60000000), + "PacketSize", Uinteger (2000)); + a->AddApplication (app); app->Start (Seconds (0.5)); app->Stop (Seconds (250.0)); diff -r d64b1561b1c2 -r e667dc0f350e samples/main-ap-wifi.cc --- a/samples/main-ap-wifi.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/main-ap-wifi.cc Wed Feb 27 22:19:39 2008 +0100 @@ -73,6 +73,7 @@ { Ptr node = CreateObject (); Ptr device = CreateObject (node, Mac48Address (macAddress)); + node->AddDevice (device); device->SetSsid (ssid); Simulator::Schedule (at, &NqapWifiNetDevice::StartBeaconing, device); device->Attach (channel); @@ -90,6 +91,7 @@ { Ptr node = CreateObject (); Ptr device = CreateObject (node, Mac48Address (macAddress)); + node->AddDevice (device); Simulator::ScheduleNow (&NqstaWifiNetDevice::StartActiveAssociation, device, ssid); device->Attach (channel); @@ -170,10 +172,13 @@ destination.SetProtocol (1); destination.SetSingleDevice (0); destination.SetPhysicalAddress (Mac48Address ("00:00:00:00:00:03")); - Ptr app = CreateObject (b, destination, - "Packet", - ConstantVariable (42), - ConstantVariable (0)); + Ptr app = + CreateObjectWith ("Node", b, + "Remote", Address (destination), + "Protocol", TypeId::LookupByName ("Packet"), + "OnTime", ConstantVariable (42), + "OffTime", ConstantVariable (0)); + b->AddApplication (app); app->Start (Seconds (0.5)); app->Stop (Seconds (43.0)); diff -r d64b1561b1c2 -r e667dc0f350e samples/main-grid-topology.cc --- a/samples/main-grid-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/main-grid-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -1,10 +1,13 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ #include "ns3/ptr.h" -#include "ns3/grid-topology.h" -#include "ns3/static-mobility-model.h" -#include "ns3/internet-node.h" +#include "ns3/node.h" #include "ns3/command-line.h" +#include "ns3/mobility-model.h" +#include "ns3/mobility-helper.h" +#include "ns3/uinteger.h" +#include "ns3/double.h" +#include "ns3/string.h" using namespace ns3; @@ -17,22 +20,30 @@ // create an array of empty nodes for testing purposes for (uint32_t i = 0; i < 120; i++) { - nodes.push_back (CreateObject ()); + nodes.push_back (CreateObject ()); } + MobilityHelper mobility; // setup the grid itself: objects are layed out // started from (-100,-100) with 20 objects per row, // the x interval between each object is 5 meters // and the y interval between each object is 20 meters - GridTopology grid (-100, -100, 20, 5, 20); - + mobility.SetPositionAllocator ("GridPositionAllocator", + "MinX", Double (-100.0), + "MinY", Double (-100.0), + "DeltaX", Double (5.0), + "DeltaY", Double (20.0), + "GridWidth", Uinteger (20), + "LayoutType", String ("RowFirst")); // each object will be attached a static position. - grid.SetMobilityModel (StaticMobilityModel::GetTypeId ()); + // i.e., once set by the "position allocator", the + // position will never change. + mobility.SetMobilityModel ("StaticMobilityModel"); // finalize the setup by attaching to each object // in the input array a position and initializing // this position with the calculated coordinates. - grid.LayoutRowFirst (nodes.begin (), nodes.end ()); + mobility.Layout (nodes.begin (), nodes.end ()); // iterate our nodes and print their position. for (std::vector >::const_iterator j = nodes.begin (); diff -r d64b1561b1c2 -r e667dc0f350e samples/main-random-topology.cc --- a/samples/main-random-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/main-random-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -4,13 +4,14 @@ #include "ns3/ptr.h" #include "ns3/mobility-model.h" -#include "ns3/mobility-model-notifier.h" -#include "ns3/static-mobility-model.h" -#include "ns3/random-topology.h" #include "ns3/default-value.h" #include "ns3/command-line.h" #include "ns3/simulator.h" #include "ns3/nstime.h" +#include "ns3/node.h" +#include "ns3/mobility-helper.h" +#include "ns3/node-list.h" +#include "ns3/string.h" using namespace ns3; @@ -24,26 +25,27 @@ int main (int argc, char *argv[]) { - DefaultValue::Bind ("RandomDiscPositionX", "100"); - DefaultValue::Bind ("RandomDiscPositionY", "50"); - DefaultValue::Bind ("RandomDiscPositionRho", "Uniform:0:30"); - - DefaultValue::Bind ("RandomTopologyPositionType", "RandomDiscPosition"); - DefaultValue::Bind ("RandomTopologyMobilityType", "StaticMobilityModel"); CommandLine::Parse (argc, argv); - RandomTopology topology; std::vector > objects; for (uint32_t i = 0; i < 10000; i++) { - Ptr notifier = CreateObject (); - notifier->TraceConnect ("/course-change", MakeCallback (&CourseChange)); - objects.push_back (notifier); + objects.push_back (CreateObject ()); } - topology.Layout (objects.begin (), objects.end ()); + MobilityHelper mobility; + mobility.EnableNotifier (); + mobility.SetPositionAllocator ("RandomDiscPositionAllocator", + "X", String ("100.0"), + "Y", String ("100.0"), + "Rho", String ("Uniform:0:30")); + mobility.SetMobilityModel ("StaticMobilityModel"); + mobility.Layout (objects.begin (), objects.end ()); + + NodeList::Connect ("/nodes/*/$MobilityModelNotifier/course-change", + MakeCallback (&CourseChange)); Simulator::StopAt (Seconds (100.0)); diff -r d64b1561b1c2 -r e667dc0f350e samples/main-random-walk.cc --- a/samples/main-random-walk.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/main-random-walk.cc Wed Feb 27 22:19:39 2008 +0100 @@ -4,14 +4,15 @@ #include "ns3/ptr.h" #include "ns3/mobility-model.h" -#include "ns3/mobility-model-notifier.h" -#include "ns3/random-topology.h" +#include "ns3/position-allocator.h" #include "ns3/default-value.h" #include "ns3/command-line.h" #include "ns3/simulator.h" #include "ns3/nstime.h" #include "ns3/node.h" #include "ns3/node-list.h" +#include "ns3/mobility-helper.h" +#include "ns3/string.h" using namespace ns3; @@ -32,24 +33,27 @@ DefaultValue::Bind ("RandomWalk2dSpeed", "Constant:1.0"); DefaultValue::Bind ("RandomWalk2dBounds", "0:200:0:100"); - DefaultValue::Bind ("RandomDiscPositionX", "100"); - DefaultValue::Bind ("RandomDiscPositionY", "50"); - DefaultValue::Bind ("RandomDiscPositionRho", "Uniform:0:30"); - - DefaultValue::Bind ("RandomTopologyPositionType", "RandomDiscPosition"); DefaultValue::Bind ("RandomTopologyMobilityType", "RandomWalk2dMobilityModel"); CommandLine::Parse (argc, argv); - RandomTopology topology; - for (uint32_t i = 0; i < 100; i++) { Ptr node = CreateObject (); - node->AggregateObject (CreateObject ()); } - topology.Layout (NodeList::Begin (), NodeList::End ()); + MobilityHelper mobility; + mobility.EnableNotifier (); + mobility.SetPositionAllocator ("RandomDiscPositionAllocator", + "X", String ("100.0"), + "Y", String ("100.0"), + "Rho", String ("Uniform:0:30")); + mobility.SetMobilityModel ("RandomWalk2dMobilityModel", + "Mode", String ("Time"), + "Time", String ("2s"), + "Speed", String ("Constant:1.0"), + "Bounds", String ("0:200:0:100")); + mobility.Layout (NodeList::Begin (), NodeList::End ()); NodeList::Connect ("/nodes/*/$MobilityModelNotifier/course-change", MakeCallback (&CourseChange)); diff -r d64b1561b1c2 -r e667dc0f350e samples/wscript --- a/samples/wscript Tue Feb 26 01:39:59 2008 +0100 +++ b/samples/wscript Wed Feb 27 22:19:39 2008 +0100 @@ -4,9 +4,6 @@ obj = bld.create_ns3_program('main-callback') obj.source = 'main-callback.cc' - obj = bld.create_ns3_program('main-ptr') - obj.source = 'main-ptr.cc' - obj = bld.create_ns3_program('main-simulator') obj.source = 'main-simulator.cc' diff -r d64b1561b1c2 -r e667dc0f350e src/applications/onoff/onoff-application.cc --- a/src/applications/onoff/onoff-application.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/onoff/onoff-application.cc Wed Feb 27 22:19:39 2008 +0100 @@ -31,10 +31,11 @@ #include "ns3/socket.h" #include "ns3/simulator.h" #include "ns3/socket-factory.h" -#include "ns3/default-value.h" #include "ns3/packet.h" -#include "ns3/composite-trace-resolver.h" +#include "ns3/uinteger.h" +#include "ns3/trace-source-accessor.h" #include "onoff-application.h" +#include "ns3/udp.h" NS_LOG_COMPONENT_DEFINE ("OnOffApplication"); @@ -42,63 +43,54 @@ namespace ns3 { -// Defaults for rate/size -static DataRateDefaultValue g_defaultRate ("OnOffApplicationDataRate", - "The data rate in on state for OnOffApplication", - DataRate ("500kb/s")); -static NumericDefaultValue g_defaultSize ("OnOffApplicationPacketSize", - "The size of packets sent in on state for OnOffApplication", - 512, 1); -// Constructors +NS_OBJECT_ENSURE_REGISTERED (OnOffApplication); -OnOffApplication::OnOffApplication(Ptr n, - const Address &remote, - std::string tid, - const RandomVariable& ontime, - const RandomVariable& offtime) - : Application(n), - m_cbrRate (g_defaultRate.GetValue ()) +TypeId +OnOffApplication::GetTypeId (void) { - Construct (n, remote, tid, - ontime, offtime, - g_defaultSize.GetValue ()); + static TypeId tid = TypeId ("OnOffApplication") + .SetParent () + .AddConstructor () + .AddAttribute ("DataRate", "The data rate in on state.", + DataRate ("500kb/s"), + MakeDataRateAccessor (&OnOffApplication::m_cbrRate), + MakeDataRateChecker ()) + .AddAttribute ("PacketSize", "The size of packets sent in on state", + Uinteger (512), + MakeUintegerAccessor (&OnOffApplication::m_pktSize), + MakeUintegerChecker (1)) + .AddAttribute ("Remote", "The address of the destination", + Address (), + MakeAddressAccessor (&OnOffApplication::m_peer), + MakeAddressChecker ()) + .AddAttribute ("OnTime", "A RandomVariable used to pick the duration of the 'On' state.", + ConstantVariable (1.0), + MakeRandomVariableAccessor (&OnOffApplication::m_onTime), + MakeRandomVariableChecker ()) + .AddAttribute ("OffTime", "A RandomVariable used to pick the duration of the 'Off' state.", + ConstantVariable (1.0), + MakeRandomVariableAccessor (&OnOffApplication::m_offTime), + MakeRandomVariableChecker ()) + .AddAttribute ("Protocol", "The type of protocol to use.", + Udp::GetTypeId (), + MakeTypeIdAccessor (&OnOffApplication::m_tid), + MakeTypeIdChecker ()) + .AddTraceSource ("Tx", "A new packet is created and is sent", + MakeTraceSourceAccessor (&OnOffApplication::m_txTrace)) + ; + return tid; } -OnOffApplication::OnOffApplication(Ptr n, - const Address &remote, - std::string tid, - const RandomVariable& ontime, - const RandomVariable& offtime, - DataRate rate, - uint32_t size) - : Application(n), - m_cbrRate (rate) + +OnOffApplication::OnOffApplication () { NS_LOG_FUNCTION; - Construct (n, remote, tid, ontime, offtime, size); -} - -void -OnOffApplication::Construct (Ptr n, - const Address &remote, - std::string tid, - const RandomVariable& onTime, - const RandomVariable& offTime, - uint32_t size) -{ - NS_LOG_FUNCTION; - m_socket = 0; - m_peer = remote; m_connected = false; - m_onTime = onTime; - m_offTime = offTime; - m_pktSize = size; m_residualBits = 0; m_lastStartTime = Seconds (0); m_maxBytes = 0; m_totBytes = 0; - m_tid = tid; } OnOffApplication::~OnOffApplication() @@ -114,21 +106,6 @@ m_maxBytes = maxBytes; } -void -OnOffApplication::SetDefaultRate (const DataRate &rate) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (&rate); - g_defaultRate.SetValue (rate); -} - -void -OnOffApplication::SetDefaultSize (uint32_t size) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (size); - g_defaultSize.SetValue (size); -} void OnOffApplication::DoDispose (void) @@ -148,8 +125,7 @@ // Create the socket if not already if (!m_socket) { - TypeId tid = TypeId::LookupByName (m_tid); - Ptr socketFactory = GetNode ()->GetObject (tid); + Ptr socketFactory = GetNode ()->GetObject (m_tid); m_socket = socketFactory->CreateSocket (); m_socket->Bind (); m_socket->Connect (m_peer); @@ -189,7 +165,6 @@ NS_LOG_FUNCTION; Simulator::Cancel(m_sendEvent); - m_socket->Close (); } // Private helpers @@ -259,17 +234,4 @@ cout << "OnOffApplication, Connection Failed" << endl; } -Ptr -OnOffApplication::GetTraceResolver (void) const -{ - Ptr resolver = Create (); - resolver->AddSource ("tx", - TraceDoc ("A new packet is created and is sent", - "Ptr", - "The newly-created packet."), - m_txTrace); - resolver->SetParentResolver (Application::GetTraceResolver ()); - return resolver; -} - } // Namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/applications/onoff/onoff-application.h --- a/src/applications/onoff/onoff-application.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/onoff/onoff-application.h Wed Feb 27 22:19:39 2008 +0100 @@ -29,8 +29,8 @@ #include "ns3/event-id.h" #include "ns3/ptr.h" #include "ns3/data-rate.h" -#include "ns3/callback-trace-source.h" #include "ns3/random-variable.h" +#include "ns3/traced-callback.h" namespace ns3 { @@ -52,60 +52,14 @@ class OnOffApplication : public Application { public: - /** - * \param n node associated to this application - * \param remote remote ip address - * \param tid TypeId of the socket factory to use. Note this - * factory should create sockets compatible with the specified - * remote address. - * \param ontime on time random variable - * \param offtime off time random variable - */ - OnOffApplication(Ptr n, - const Address &remote, - std::string tid, - const RandomVariable& ontime, - const RandomVariable& offtime); + static TypeId GetTypeId (void); - /** - * \param n node associated to this application - * \param remote remote ip address - * \param tid TypeId of the socket factory to use. Note this - * factory should create sockets compatible with the specified - * remote address. - * \param ontime on time random variable - * \param offtime off time random variable - * \param rate data rate when on - * \param size size of packets when sending data. - */ - OnOffApplication(Ptr n, - const Address &remote, - std::string tid, - const RandomVariable& ontime, - const RandomVariable& offtime, - DataRate rate, - uint32_t size); + OnOffApplication (); virtual ~OnOffApplication(); void SetMaxBytes(uint32_t maxBytes); - /** - * \param r the data rate - * - * Set the data rate to use for every OnOffApplication for which - * the user does not specify an explicit data rate. - */ - static void SetDefaultRate(const DataRate & r); - - /** - * \param size the packet size - * - * Set the packet size to use for every OnOffApplication for - * which the user does not specify an explicit packet size. - */ - static void SetDefaultSize (uint32_t size); - protected: virtual void DoDispose (void); private: @@ -129,8 +83,8 @@ Ptr m_socket; // Associated socket Address m_peer; // Peer address bool m_connected; // True if connected - RandomVariable m_onTime; // rng for On Time - RandomVariable m_offTime; // rng for Off Time + RandomVariable m_onTime; // rng for On Time + RandomVariable m_offTime; // rng for Off Time DataRate m_cbrRate; // Rate that data is generated uint32_t m_pktSize; // Size of packets uint32_t m_residualBits; // Number of generated, but not sent, bits @@ -140,11 +94,10 @@ EventId m_startStopEvent; // Event id for next start or stop event EventId m_sendEvent; // Eventid of pending "send packet" event bool m_sending; // True if currently in sending state - std::string m_tid; - CallbackTraceSource > m_txTrace; + TypeId m_tid; + TracedCallback > m_txTrace; private: - virtual Ptr GetTraceResolver (void) const; void ScheduleNextTx(); void ScheduleStartEvent(); void ScheduleStopEvent(); diff -r d64b1561b1c2 -r e667dc0f350e src/applications/packet-sink/packet-sink.cc --- a/src/applications/packet-sink/packet-sink.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/packet-sink/packet-sink.cc Wed Feb 27 22:19:39 2008 +0100 @@ -25,7 +25,8 @@ #include "ns3/simulator.h" #include "ns3/socket-factory.h" #include "ns3/packet.h" -#include "ns3/composite-trace-resolver.h" +#include "ns3/trace-source-accessor.h" +#include "ns3/udp.h" #include "packet-sink.h" using namespace std; @@ -33,25 +34,30 @@ namespace ns3 { NS_LOG_COMPONENT_DEFINE ("PacketSinkApplication"); - -// Constructors +NS_OBJECT_ENSURE_REGISTERED (PacketSink); -PacketSink::PacketSink (Ptr n, - const Address &local, - std::string tid) - : Application(n) +TypeId +PacketSink::GetTypeId (void) { - Construct (n, local, tid); + static TypeId tid = TypeId ("PacketSink") + .SetParent () + .AddAttribute ("Local", "The Address on which to Bind the rx socket.", + Address (), + MakeAddressAccessor (&PacketSink::m_local), + MakeAddressChecker ()) + .AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.", + Udp::GetTypeId (), + MakeTypeIdAccessor (&PacketSink::m_tid), + MakeTypeIdChecker ()) + .AddTraceSource ("Rx", "A packet has been received", + MakeTraceSourceAccessor (&PacketSink::m_rxTrace)) + ; + return tid; } -void -PacketSink::Construct (Ptr n, - const Address &local, - std::string tid) +PacketSink::PacketSink () { m_socket = 0; - m_local = local; - m_tid = tid; } PacketSink::~PacketSink() @@ -73,9 +79,8 @@ // Create the socket if not already if (!m_socket) { - TypeId tid = TypeId::LookupByName (m_tid); Ptr socketFactory = - GetNode ()->GetObject (tid); + GetNode ()->GetObject (m_tid); m_socket = socketFactory->CreateSocket (); m_socket->Bind (m_local); m_socket->Listen (0); @@ -116,19 +121,4 @@ socket->Close (); } -Ptr -PacketSink::GetTraceResolver (void) const -{ - Ptr resolver = Create (); - resolver->AddSource ("rx", - TraceDoc ("A new packet has been received", - "Ptr", - "The newly-received packet.", - "const Address &", - "The source address of the received packet."), - m_rxTrace); - resolver->SetParentResolver (Application::GetTraceResolver ()); - return resolver; -} - } // Namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/applications/packet-sink/packet-sink.h --- a/src/applications/packet-sink/packet-sink.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/packet-sink/packet-sink.h Wed Feb 27 22:19:39 2008 +0100 @@ -24,7 +24,7 @@ #include "ns3/application.h" #include "ns3/event-id.h" #include "ns3/ptr.h" -#include "ns3/callback-trace-source.h" +#include "ns3/traced-callback.h" #include "ns3/address.h" namespace ns3 { @@ -53,14 +53,13 @@ class PacketSink : public Application { public: + static TypeId GetTypeId (void); /** * \param n node associated to this application * \param local local address to bind to * \param tid string to identify transport protocol of interest */ - PacketSink (Ptr n, - const Address &local, - std::string tid); + PacketSink (); virtual ~PacketSink (); @@ -70,20 +69,14 @@ // inherited from Application base class. virtual void StartApplication (void); // Called at time specified by Start virtual void StopApplication (void); // Called at time specified by Stop - // inherited from Object base class. - virtual Ptr GetTraceResolver (void) const; - - void Construct (Ptr n, - const Address &local, - std::string tid); virtual void Receive (Ptr socket, Ptr packet, const Address& from); virtual void CloseConnection (Ptr socket); Ptr m_socket; // Associated socket Address m_local; // Local address to bind to - std::string m_tid; // Protocol name (e.g., "Udp") - CallbackTraceSource, const Address &> m_rxTrace; + TypeId m_tid; // Protocol TypeId + TracedCallback, const Address &> m_rxTrace; }; diff -r d64b1561b1c2 -r e667dc0f350e src/applications/udp-echo/udp-echo-client.cc --- a/src/applications/udp-echo/udp-echo-client.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/udp-echo/udp-echo-client.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,27 +23,50 @@ #include "ns3/simulator.h" #include "ns3/socket-factory.h" #include "ns3/packet.h" +#include "ns3/uinteger.h" #include "udp-echo-client.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE ("UdpEchoClientApplication"); +NS_OBJECT_ENSURE_REGISTERED (UdpEchoClient); -UdpEchoClient::UdpEchoClient ( - Ptr n, - Ipv4Address serverAddress, - uint16_t serverPort, - uint32_t count, - Time interval, - uint32_t size) -: - Application(n) +TypeId +UdpEchoClient::GetTypeId (void) +{ + static TypeId tid = TypeId ("UdpEchoClient") + .SetParent () + .AddConstructor () + .AddAttribute ("MaxPackets", "XXX", + Uinteger (100), + MakeUintegerAccessor (&UdpEchoClient::m_count), + MakeUintegerChecker ()) + .AddAttribute ("Interval", "XXX", + Seconds (1.0), + MakeTimeAccessor (&UdpEchoClient::m_interval), + MakeTimeChecker ()) + .AddAttribute ("RemoteIpv4", "XXX", + Ipv4Address (), + MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress), + MakeIpv4AddressChecker ()) + .AddAttribute ("RemotePort", "XXX", + Uinteger (0), + MakeUintegerAccessor (&UdpEchoClient::m_peerPort), + MakeUintegerChecker ()) + .AddAttribute ("PacketSize", "Size of packets generated", + Uinteger (100), + MakeUintegerAccessor (&UdpEchoClient::m_size), + MakeUintegerChecker ()) + ; + return tid; +} + +UdpEchoClient::UdpEchoClient () { NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << n << serverAddress << serverPort << count - << interval << size); - - Construct (n, serverAddress, serverPort, count, interval, size); + m_sent = 0; + m_socket = 0; + m_sendEvent = EventId (); } UdpEchoClient::~UdpEchoClient() @@ -52,32 +75,6 @@ } void -UdpEchoClient::Construct ( - Ptr n, - Ipv4Address serverAddress, - uint16_t serverPort, - uint32_t count, - Time interval, - uint32_t size) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << n << serverAddress << serverPort - << count << interval << size); - - m_node = n; - m_serverAddress = serverAddress; - m_serverPort = serverPort; - m_count = count; - m_interval = interval; - m_size = size; - - m_sent = 0; - m_socket = 0; - m_peer = InetSocketAddress (serverAddress, serverPort); - m_sendEvent = EventId (); -} - -void UdpEchoClient::DoDispose (void) { NS_LOG_FUNCTION; @@ -96,7 +93,7 @@ GetNode ()->GetObject (tid); m_socket = socketFactory->CreateSocket (); m_socket->Bind (); - m_socket->Connect (m_peer); + m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort)); } m_socket->SetRecvCallback(MakeCallback(&UdpEchoClient::Receive, this)); @@ -136,7 +133,7 @@ m_socket->Send (p); ++m_sent; - NS_LOG_INFO ("Sent " << m_size << " bytes to " << m_serverAddress); + NS_LOG_INFO ("Sent " << m_size << " bytes to " << m_peerAddress); if (m_sent < m_count) { diff -r d64b1561b1c2 -r e667dc0f350e src/applications/udp-echo/udp-echo-client.h --- a/src/applications/udp-echo/udp-echo-client.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/udp-echo/udp-echo-client.h Wed Feb 27 22:19:39 2008 +0100 @@ -32,8 +32,9 @@ class UdpEchoClient : public Application { public: - UdpEchoClient (Ptr n, Ipv4Address serverAddr, uint16_t serverPort, - uint32_t count, Time interval, uint32_t size); + static TypeId GetTypeId (void); + + UdpEchoClient (); virtual ~UdpEchoClient (); @@ -41,8 +42,6 @@ virtual void DoDispose (void); private: - void Construct (Ptr n, Ipv4Address serverAddr, uint16_t serverPort, - uint32_t count, Time interval, uint32_t size); virtual void StartApplication (void); virtual void StopApplication (void); @@ -52,16 +51,14 @@ void Receive(Ptr socket, Ptr packet, const Address &from); - Ptr m_node; - Ipv4Address m_serverAddress; - uint16_t m_serverPort; uint32_t m_count; Time m_interval; uint32_t m_size; uint32_t m_sent; Ptr m_socket; - Address m_peer; + Ipv4Address m_peerAddress; + uint16_t m_peerPort; EventId m_sendEvent; }; diff -r d64b1561b1c2 -r e667dc0f350e src/applications/udp-echo/udp-echo-server.cc --- a/src/applications/udp-echo/udp-echo-server.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/udp-echo/udp-echo-server.cc Wed Feb 27 22:19:39 2008 +0100 @@ -24,23 +24,32 @@ #include "ns3/simulator.h" #include "ns3/socket-factory.h" #include "ns3/packet.h" +#include "ns3/uinteger.h" #include "udp-echo-server.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE ("UdpEchoServerApplication"); +NS_OBJECT_ENSURE_REGISTERED (UdpEchoServer); -UdpEchoServer::UdpEchoServer ( - Ptr n, - uint16_t port) -: - Application(n) +TypeId +UdpEchoServer::GetTypeId (void) +{ + static TypeId tid = TypeId ("UdpEchoServer") + .SetParent () + .AddConstructor () + .AddAttribute ("Port", "Client Port", + Uinteger (0), + MakeUintegerAccessor (&UdpEchoServer::m_port), + MakeUintegerChecker ()) + ; + return tid; +} + +UdpEchoServer::UdpEchoServer () { NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << n << port); - - Construct (n, port); } UdpEchoServer::~UdpEchoServer() @@ -49,21 +58,6 @@ } void -UdpEchoServer::Construct ( - Ptr n, - uint16_t port) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << n << port); - - m_node = n; - m_port = port; - - m_socket = 0; - m_local = InetSocketAddress (Ipv4Address::GetAny (), port); -} - -void UdpEchoServer::DoDispose (void) { NS_LOG_FUNCTION; @@ -81,7 +75,8 @@ Ptr socketFactory = GetNode ()->GetObject (tid); m_socket = socketFactory->CreateSocket (); - m_socket->Bind (m_local); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), m_port); + m_socket->Bind (local); } m_socket->SetRecvCallback(MakeCallback(&UdpEchoServer::Receive, this)); diff -r d64b1561b1c2 -r e667dc0f350e src/applications/udp-echo/udp-echo-server.h --- a/src/applications/udp-echo/udp-echo-server.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/applications/udp-echo/udp-echo-server.h Wed Feb 27 22:19:39 2008 +0100 @@ -32,23 +32,21 @@ class UdpEchoServer : public Application { public: - UdpEchoServer (Ptr n, uint16_t clientPort); + static TypeId GetTypeId (void); + UdpEchoServer (); virtual ~UdpEchoServer (); protected: virtual void DoDispose (void); private: - void Construct (Ptr n, uint16_t clientPort); virtual void StartApplication (void); virtual void StopApplication (void); void Receive(Ptr socket, Ptr packet, const Address &from); - Ptr m_node; uint16_t m_port; - Ptr m_socket; Address m_local; }; diff -r d64b1561b1c2 -r e667dc0f350e src/common/data-rate.cc --- a/src/common/data-rate.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/common/data-rate.cc Wed Feb 27 22:19:39 2008 +0100 @@ -125,25 +125,15 @@ namespace ns3 { +VALUE_HELPER_CPP (DataRate); + +DataRate::DataRate () + : m_bps (0) +{} + DataRate::DataRate(uint64_t bps) :m_bps(bps) -{ -} - -DataRate::DataRate (const std::string s) - : m_bps(DataRate::Parse(s)) -{ -} - -uint64_t DataRate::Parse(const std::string s) -{ - uint64_t v; - if (!DoParse (s, &v)) - { - NS_FATAL_ERROR("Can't Parse data rate "<> (std::istream &is, DataRate &rate) +{ + std::string value; + is >> value; + uint64_t v; + bool ok = DoParse (value, &v); + if (!ok) + { + is.setstate (std::ios_base::failbit); + } + rate = DataRate (v); + return is; +} + + + double operator*(const DataRate& lhs, const Time& rhs) { return rhs.GetSeconds()*lhs.GetBitRate(); diff -r d64b1561b1c2 -r e667dc0f350e src/common/data-rate.h --- a/src/common/data-rate.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/common/data-rate.h Wed Feb 27 22:19:39 2008 +0100 @@ -27,6 +27,8 @@ #include #include "ns3/nstime.h" #include "ns3/default-value.h" +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" namespace ns3 { @@ -46,7 +48,8 @@ */ class DataRate { - public: +public: + DataRate (); /** * \brief Integer constructor * @@ -55,23 +58,8 @@ * non-trivial bitrate availiable. */ DataRate (uint64_t bps); - - /** - * \brief String constructor - * - * Construct a DataRate from a string. The supported strings have a - * numerical portion, followed by units in the following format: - * - Prefix: nothing, "k", "M", "G" - * - Data Unit: "b, "B" - * - Time Suffix: "ps", "/s" \n - * The prefixes are SI powers of 10 (10^0,10^3,10^6,10^9 respectively).\n - * The units are the bit, and the (8-bit) byte respectively.\n - * Both time suffixes denote "per second". Some supported examples include - * "20B/s", "56kbps", "4.4MB/s", and "100Gb/s". Any malformed string causes - * a fatal error. - */ - DataRate (const std::string s); - + DataRate (std::string rate); + bool operator < (const DataRate& rhs) const; bool operator <= (const DataRate& rhs) const; bool operator > (const DataRate& rhs) const; @@ -93,11 +81,18 @@ * \return The underlying bitrate in bits per second */ uint64_t GetBitRate() const; - - private: + + VALUE_HELPER_HEADER_1 (DataRate); +private: uint64_t m_bps; static uint64_t Parse(const std::string); }; + +std::ostream &operator << (std::ostream &os, const DataRate &rate); +std::istream &operator >> (std::istream &is, DataRate &rate); + +VALUE_HELPER_HEADER_2 (DataRate); + /** * \param lhs * \param rhs @@ -122,6 +117,6 @@ DataRate m_value; }; -};//namespace ns3 +} //namespace ns3 #endif /* DATA_RATE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/common/error-model.cc --- a/src/common/error-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/common/error-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -27,24 +27,25 @@ #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/random-variable.h" -#include "ns3/default-value.h" -#include "ns3/type-id-default-value.h" +#include "ns3/boolean.h" +#include "ns3/enum.h" +#include "ns3/double.h" NS_LOG_COMPONENT_DEFINE ("ErrorModel"); namespace ns3 { -static TypeIdDefaultValue g_interfaceIdErrorModelDefaultValue ("ErrorModel", - "Error Model", - ErrorModel::GetTypeId (), - "RateErrorModel"); - NS_OBJECT_ENSURE_REGISTERED (ErrorModel); TypeId ErrorModel::GetTypeId (void) { static TypeId tid = TypeId ("ErrorModel") - .SetParent (); + .SetParent () + .AddAttribute ("IsEnabled", "Whether this ErrorModel is enabled or not.", + Boolean (true), + MakeBooleanAccessor (&ErrorModel::m_enable), + MakeBooleanChecker ()) + ; return tid; } @@ -59,15 +60,6 @@ NS_LOG_FUNCTION; } -Ptr -ErrorModel::CreateDefault (void) -{ - NS_LOG_FUNCTION; - TypeId interfaceId = g_interfaceIdErrorModelDefaultValue.GetValue (); - Ptr em = interfaceId.CreateObject ()->GetObject (); - return em; -} - bool ErrorModel::IsCorrupt (Ptr p) { @@ -111,36 +103,35 @@ // RateErrorModel // -// Defaults for rate/size -static NumericDefaultValue g_defaultRateErrorModelErrorRate - ("RateErrorModelErrorRate", "The error rate for the error model", 0.0); - -static EnumDefaultValue - g_defaultRateErrorModelErrorUnit ("RateErrorModelErrorUnit", - "The error unit for this error model", - EU_BYTE, "EU_BYTE", - EU_PKT, "EU_PKT", - EU_BIT, "EU_BIT", - 0, (void*)0); - NS_OBJECT_ENSURE_REGISTERED (RateErrorModel); TypeId RateErrorModel::GetTypeId (void) { static TypeId tid = TypeId ("RateErrorModel") .SetParent () - .AddConstructor (); + .AddConstructor () + .AddAttribute ("ErrorUnit", "The error unit", + Enum (EU_BYTE), + MakeEnumAccessor (&RateErrorModel::m_unit), + MakeEnumChecker (EU_BYTE, "EU_BYTE", + EU_PKT, "EU_PKT", + EU_BIT, "EU_BIT")) + .AddAttribute ("ErrorRate", "The error rate.", + Double (0.0), + MakeDoubleAccessor (&RateErrorModel::m_rate), + MakeDoubleChecker ()) + .AddAttribute ("RanVar", "The decision variable attached to this error model.", + UniformVariable (0.0, 1.0), + MakeRandomVariableAccessor (&RateErrorModel::m_ranvar), + MakeRandomVariableChecker ()) + ; return tid; } -RateErrorModel::RateErrorModel () : - m_unit (g_defaultRateErrorModelErrorUnit.GetValue() ), - m_rate (g_defaultRateErrorModelErrorRate.GetValue() ) +RateErrorModel::RateErrorModel () { NS_LOG_FUNCTION; - // Assume a uniform random variable if user does not specify - m_ranvar = UniformVariable (); } RateErrorModel::~RateErrorModel () @@ -248,7 +239,8 @@ { static TypeId tid = TypeId ("ListErrorModel") .SetParent () - .AddConstructor (); + .AddConstructor () + ; return tid; } diff -r d64b1561b1c2 -r e667dc0f350e src/common/packet.h --- a/src/common/packet.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/common/packet.h Wed Feb 27 22:19:39 2008 +0100 @@ -31,6 +31,7 @@ #include "ns3/callback.h" #include "ns3/assert.h" #include "ns3/ptr.h" +#include "ns3/object-base.h" namespace ns3 { @@ -73,7 +74,7 @@ * The performance aspects of the Packet API are discussed in * \ref packetperf */ -class Packet { +class Packet : public ObjectBase { public: void Ref (void) const; void Unref (void) const; diff -r d64b1561b1c2 -r e667dc0f350e src/core/attribute-accessor-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/attribute-accessor-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,192 @@ +#ifndef ATTRIBUTE_ACCESSOR_HELPER_H +#define ATTRIBUTE_ACCESSOR_HELPER_H + +namespace ns3 { + +template +Ptr +MakeAccessorHelper (T1 a1); + +template +Ptr +MakeAccessorHelper (T1 a1, T2 a2); + +} // namespace ns3 + +/*************************************************************** + * The implementation of the above functions. + ***************************************************************/ + +#include "type-traits.h" + +namespace ns3 { + +template +class AccessorHelper : public AttributeAccessor +{ +public: + AccessorHelper () {} + + virtual bool Set (ObjectBase * object, Attribute val) const { + const U *value = val.DynCast (); + if (value == 0) + { + return false; + } + T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + return DoSet (obj, value); + } + + virtual bool Get (const ObjectBase * object, Attribute val) const { + U *value = val.DynCast (); + if (value == 0) + { + return false; + } + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + return DoGet (obj, value); + } + + +private: + virtual bool DoSet (T *object, const U *v) const = 0; + virtual bool DoGet (const T *object, U *v) const = 0; +}; + +template +Ptr +DoMakeAccessorHelperOne (U T::*memberVariable) +{ + class MemberVariable : public AccessorHelper + { + public: + MemberVariable (U T::*memberVariable) + : AccessorHelper (), + m_memberVariable (memberVariable) + {} + private: + virtual bool DoSet (T *object, const V *v) const { + (object->*m_memberVariable) = U (v->Get ()); + return true; + } + virtual bool DoGet (const T *object, V *v) const { + v->Set (object->*m_memberVariable); + return true; + } + + U T::*m_memberVariable; + }; + return Ptr (new MemberVariable (memberVariable), false); +} + +template +Ptr +DoMakeAccessorHelperOne (U (T::*getter) (void) const) +{ + class MemberMethod : public AccessorHelper + { + public: + MemberMethod (U (T::*getter) (void) const) + : AccessorHelper (), + m_getter (getter) + {} + private: + virtual bool DoSet (T *object, const V *v) const { + return false; + } + virtual bool DoGet (const T *object, V *v) const { + v->Set ((object->*m_getter) ()); + return true; + } + U (T::*m_getter) (void) const; + }; + return Ptr (new MemberMethod (getter), false); +} + + +template +Ptr +DoMakeAccessorHelperOne (void (T::*setter) (U)) +{ + class MemberMethod : public AccessorHelper + { + public: + MemberMethod (void (T::*setter) (U)) + : AccessorHelper (), + m_setter (setter) + {} + private: + virtual bool DoSet (T *object, const V *v) const { + (object->*m_setter) (v->Get ()); + return true; + } + virtual void DoGet (const T *object, V *v) const { + return false; + } + void (T::*m_setter) (U); + }; + return Ptr (new MemberMethod (setter), false); +} + +template +Ptr +DoMakeAccessorHelperTwo (void (T::*setter) (U), + V (T::*getter) (void) const) +{ + class MemberMethod : public AccessorHelper + { + public: + MemberMethod (void (T::*setter) (U), + V (T::*getter) (void) const) + : AccessorHelper (), + m_setter (setter), + m_getter (getter) + {} + private: + virtual bool DoSet (T *object, const W *v) const { + (object->*m_setter) (v->Get ()); + return true; + } + virtual bool DoGet (const T *object, W *v) const { + v->Set ((object->*m_getter) ()); + return true; + } + void (T::*m_setter) (U); + V (T::*m_getter) (void) const; + }; + return Ptr (new MemberMethod (setter, getter), false); +} + +template +Ptr +DoMakeAccessorHelperTwo (V (T::*getter) (void) const, + void (T::*setter) (U)) +{ + return DoMakeAccessorHelperTwo (setter, getter); +} + +template +Ptr +MakeAccessorHelper (T1 a1) +{ + return DoMakeAccessorHelperOne (a1); +} + +template +Ptr +MakeAccessorHelper (T1 a1, T2 a2) +{ + return DoMakeAccessorHelperTwo (a1, a2); +} + +} // namespace ns3 + +#endif /* ATTRIBUTE_ACCESSOR_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/attribute-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/attribute-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,123 @@ +#ifndef VALUE_HELPER_H +#define VALUE_HELPER_H + +#include "attribute.h" +#include "object-base.h" +#include "attribute-accessor-helper.h" +#include +#include "fatal-error.h" + +#define ATTRIBUTE_ACCESSOR_DEFINE(type) \ + template \ + Ptr Make##type##Accessor (T1 a1) \ + { \ + return MakeAccessorHelper (a1); \ + } \ + template \ + Ptr Make##type##Accessor (T1 a1, T2 a2) \ + { \ + return MakeAccessorHelper (a1, a2); \ + } + +#define ATTRIBUTE_VALUE_DEFINE(type) \ + class type##Value : public AttributeValue \ + { \ + public: \ + type##Value (const type &value); \ + void Set (const type &value); \ + type Get (void) const; \ + virtual Attribute Copy (void) const; \ + virtual std::string SerializeToString (Ptr checker) const; \ + virtual bool DeserializeFromString (std::string value, Ptr checker); \ + type##Value (Attribute value); \ + operator Attribute () const; \ + private: \ + type m_value; \ + }; + +#define ATTRIBUTE_CONVERTER_DEFINE(type) \ + type (Attribute value); \ + operator Attribute () const; + +#define ATTRIBUTE_CHECKER_DEFINE(type) \ + class type##Checker : public AttributeChecker {}; \ + Ptr Make##type##Checker (void); \ + +#define ATTRIBUTE_VALUE_IMPLEMENT(type) \ + type##Value::type##Value (const type &value) \ + : m_value (value) {} \ + void type##Value::Set (const type &v) { \ + m_value = v; \ + } \ + type type##Value::Get (void) const { \ + return m_value; \ + } \ + Attribute \ + type##Value::Copy (void) const { \ + return Attribute::Create (*this); \ + } \ + std::string \ + type##Value::SerializeToString (Ptr checker) const { \ + std::ostringstream oss; \ + oss << m_value; \ + return oss.str (); \ + } \ + bool \ + type##Value::DeserializeFromString (std::string value, Ptr checker) { \ + std::istringstream iss; \ + iss.str (value); \ + iss >> m_value; \ + return !iss.bad () && !iss.fail (); \ + } \ + type##Value::type##Value (Attribute value) \ + { \ + type##Value *v = value.DynCast (); \ + if (v == 0) \ + { \ + NS_FATAL_ERROR ("Unexpected type of value. Expected \"" << #type << "Value\""); \ + } \ + m_value = v->Get (); \ + } \ + type##Value::operator Attribute () const \ + { \ + return Attribute::Create (*this); \ + } + +#define ATTRIBUTE_CHECKER_IMPLEMENT(type) \ + Ptr Make##type##Checker (void) \ + { \ + return MakeSimpleAttributeChecker (); \ + } \ + +#define ATTRIBUTE_CONVERTER_IMPLEMENT(type) \ + type::type (Attribute value) \ + { \ + const type##Value *v = value.DynCast (); \ + if (v == 0) \ + { \ + NS_FATAL_ERROR ("Unexpected type of value. Expected \"" << #type << "Value\""); \ + } \ + *this = v->Get (); \ + } \ + type::operator Attribute () const \ + { \ + return Attribute::Create (*this); \ + } + + +#define VALUE_HELPER_HEADER_1(type) \ + ATTRIBUTE_CONVERTER_DEFINE (type) + +#define VALUE_HELPER_HEADER_2(type) \ + ATTRIBUTE_VALUE_DEFINE (type); \ + ATTRIBUTE_ACCESSOR_DEFINE (type); \ + ATTRIBUTE_CHECKER_DEFINE (type); + +#define VALUE_HELPER_CPP(type) \ + ATTRIBUTE_CHECKER_IMPLEMENT (type); \ + ATTRIBUTE_CONVERTER_IMPLEMENT (type); \ + ATTRIBUTE_VALUE_IMPLEMENT (type); + + + +#endif /* VALUE_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/attribute-test.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/attribute-test.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,475 @@ +#ifdef RUN_SELF_TESTS +#include "test.h" +#include "object.h" +#include "boolean.h" +#include "integer.h" +#include "uinteger.h" +#include "enum.h" +#include "string.h" +#include "random-variable.h" +#include "double.h" +#include "object-vector.h" +#include "traced-value.h" +#include "trace-source-accessor.h" + +namespace ns3 { + +class ValueClassTest +{ +public: + ValueClassTest () {} + VALUE_HELPER_HEADER_1 (ValueClassTest); +private: + int m_v; +}; +bool operator != (const ValueClassTest &a, const ValueClassTest &b) +{ + return true; +} +std::ostream & operator << (std::ostream &os, ValueClassTest v) +{ + return os; +} +std::istream & operator >> (std::istream &is, ValueClassTest &v) +{ + return is; +} +VALUE_HELPER_HEADER_2 (ValueClassTest); +VALUE_HELPER_CPP (ValueClassTest); + +class AttributeTest : public Test +{ +public: + AttributeTest (); + virtual bool RunTests (void); +private: + void NotifySource1 (int8_t old, int8_t n) { + m_got1 = n; + } + void NotifySource2 (double a, int b, float c) { + m_got2 = a; + } + void NotifySourceValue (ValueClassTest old, ValueClassTest n) { + m_gotValue = n; + } + int64_t m_got1; + double m_got2; + ValueClassTest m_gotValue; +}; + +class Derived : public Object +{ +public: + static TypeId GetTypeId (void) { + static TypeId tid = TypeId ("Derived") + .SetParent () + ; + return tid; + } +}; + +class AttributeObjectTest : public Object +{ +public: + enum TestEnum { + TEST_A, + TEST_B, + TEST_C + }; + static TypeId GetTypeId (void) { + static TypeId tid = TypeId ("AttributeObjectTest") + .SetParent () + .AddAttribute ("TestBoolName", "help text", + Boolean (false), + MakeBooleanAccessor (&AttributeObjectTest::m_boolTest), + MakeBooleanChecker ()) + .AddAttribute ("TestBoolA", "help text", + Boolean (false), + MakeBooleanAccessor (&AttributeObjectTest::DoSetTestB, + &AttributeObjectTest::DoGetTestB), + MakeBooleanChecker ()) + .AddAttribute ("TestPtr", "help text", + Ptr (0), + MakePtrAccessor (&AttributeObjectTest::m_derived), + MakePtrChecker ()) + .AddAttribute ("TestInt16", "help text", + Integer (-2), + MakeIntegerAccessor (&AttributeObjectTest::m_int16), + MakeIntegerChecker ()) + .AddAttribute ("TestInt16WithBounds", "help text", + Integer (-2), + MakeIntegerAccessor (&AttributeObjectTest::m_int16WithBounds), + MakeIntegerChecker (-5, 10)) + .AddAttribute ("TestInt16SetGet", "help text", + Integer (6), + MakeIntegerAccessor (&AttributeObjectTest::DoSetInt16, + &AttributeObjectTest::DoGetInt16), + MakeIntegerChecker ()) + .AddAttribute ("TestUint8", "help text", + Uinteger (1), + MakeUintegerAccessor (&AttributeObjectTest::m_uint8), + MakeUintegerChecker ()) + .AddAttribute ("TestEnum", "help text", + Enum (TEST_A), + MakeEnumAccessor (&AttributeObjectTest::m_enum), + MakeEnumChecker (TEST_A, "TestA", + TEST_B, "TestB", + TEST_C, "TestC")) + .AddAttribute ("TestRandom", "help text", + ConstantVariable (1.0), + MakeRandomVariableAccessor (&AttributeObjectTest::m_random), + MakeRandomVariableChecker ()) + .AddAttribute ("TestFloat", "help text", + Double (-1.1), + MakeDoubleAccessor (&AttributeObjectTest::m_float), + MakeDoubleChecker ()) + .AddAttribute ("TestVector1", "help text", + ObjectVector (), + MakeObjectVectorAccessor (&AttributeObjectTest::m_vector1), + MakeObjectVectorChecker ()) + .AddAttribute ("TestVector2", "help text", + ObjectVector (), + MakeObjectVectorAccessor (&AttributeObjectTest::DoGetVectorN, + &AttributeObjectTest::DoGetVector), + MakeObjectVectorChecker ()) + .AddAttribute ("IntegerTraceSource1", "help text", + Integer (-2), + MakeIntegerAccessor (&AttributeObjectTest::m_intSrc1), + MakeIntegerChecker ()) + .AddAttribute ("IntegerTraceSource2", "help text", + Integer (-2), + MakeIntegerAccessor (&AttributeObjectTest::DoSetIntSrc, + &AttributeObjectTest::DoGetIntSrc), + MakeIntegerChecker ()) + .AddAttribute ("ValueClassSource", "help text", + ValueClassTest (), + MakeValueClassTestAccessor (&AttributeObjectTest::m_valueSrc), + MakeValueClassTestChecker ()) + .AddTraceSource ("Source1", "help test", + MakeTraceSourceAccessor (&AttributeObjectTest::m_intSrc1)) + .AddTraceSource ("Source2", "help text", + MakeTraceSourceAccessor (&AttributeObjectTest::m_cb)) + .AddTraceSource ("ValueSource", "help text", + MakeTraceSourceAccessor (&AttributeObjectTest::m_valueSrc)) + ; + + return tid; + } + + void AddToVector1 (void) { + m_vector1.push_back (CreateObject ()); + } + void AddToVector2 (void) { + m_vector2.push_back (CreateObject ()); + } + + void InvokeCb (double a, int b, float c) { + m_cb (a,b,c); + } + +private: + void DoSetTestB (bool v) { + m_boolTestA = v; + } + bool DoGetTestB (void) const { + return m_boolTestA; + } + int16_t DoGetInt16 (void) const { + return m_int16SetGet; + } + void DoSetInt16 (int16_t v) { + m_int16SetGet = v; + } + uint32_t DoGetVectorN (void) const { + return m_vector2.size (); + } + Ptr DoGetVector (uint32_t i) const { + return m_vector2[i]; + } + void DoSetIntSrc (int8_t v) { + m_intSrc2 = v; + } + int8_t DoGetIntSrc (void) const { + return m_intSrc2; + } + bool m_boolTestA; + bool m_boolTest; + Ptr m_derived; + int16_t m_int16; + int16_t m_int16WithBounds; + int16_t m_int16SetGet; + uint8_t m_uint8; + float m_float; + enum TestEnum m_enum; + RandomVariable m_random; + std::vector > m_vector1; + std::vector > m_vector2; + TracedValue m_intSrc1; + TracedValue m_intSrc2; + TracedCallback m_cb; + TracedValue m_valueSrc; +}; + + +#define CHECK_GET_STR(p,name,value) \ + { \ + std::string expected = value; \ + std::string got; \ + bool ok = p->GetAttribute (name, got); \ + NS_TEST_ASSERT (ok); \ + NS_TEST_ASSERT_EQUAL (got, expected); \ + } +#define CHECK_GET_PARAM(p,name,type,value) \ + { \ + const type expected = value; \ + type got = value; \ + Attribute v = p->GetAttribute (name); \ + got = v; \ + NS_TEST_ASSERT_EQUAL (got.Get (), expected.Get ()); \ + } + +NS_OBJECT_ENSURE_REGISTERED (AttributeObjectTest); + +AttributeTest::AttributeTest () + : Test ("Attribute") +{} +bool +AttributeTest::RunTests (void) +{ + bool result = true; + + AttributeList params; + Ptr p; + NS_TEST_ASSERT (params.Set ("AttributeObjectTest::TestBoolName", String ("false"))); + p = CreateObject (params); + CHECK_GET_STR (p, "TestBoolName", "false"); + CHECK_GET_PARAM (p, "TestBoolName", Boolean, false); + + NS_TEST_ASSERT (p->SetAttribute("TestBoolName", String ("true"))); + CHECK_GET_STR (p, "TestBoolName", "true"); + CHECK_GET_PARAM (p, "TestBoolName", Boolean, true); + + NS_TEST_ASSERT (p->SetAttribute("TestBoolName", Boolean (false))); + CHECK_GET_STR (p, "TestBoolName", "false"); + CHECK_GET_PARAM (p, "TestBoolName", Boolean, false); + + p = CreateObjectWith ("TestBoolName", String ("true")); + CHECK_GET_STR (p, "TestBoolName", "true"); + CHECK_GET_PARAM (p, "TestBoolName", Boolean, true); + + p = CreateObjectWith ("TestBoolName", Boolean (true)); + CHECK_GET_STR (p, "TestBoolName", "true"); + CHECK_GET_PARAM (p, "TestBoolName", Boolean, true); + + NS_TEST_ASSERT (p->SetAttribute("TestBoolA", String ("false"))); + CHECK_GET_STR (p, "TestBoolA", "false"); + CHECK_GET_PARAM (p, "TestBoolA", Boolean, false); + + NS_TEST_ASSERT (p->SetAttribute("TestBoolA", String ("true"))); + CHECK_GET_STR (p, "TestBoolA", "true"); + CHECK_GET_PARAM (p, "TestBoolA", Boolean, true); + + + Ptr derived = p->GetAttribute ("TestPtr"); + NS_TEST_ASSERT (derived == 0); + derived = Create (); + NS_TEST_ASSERT (p->SetAttribute("TestPtr", derived)); + Ptr stored = p->GetAttribute ("TestPtr"); + NS_TEST_ASSERT (stored == derived); + Ptr storedBase = p->GetAttribute ("TestPtr"); + NS_TEST_ASSERT (stored == storedBase); + Ptr x = p->GetAttribute ("TestPtr"); + NS_TEST_ASSERT (x == 0); + + p = CreateObjectWith ("TestPtr", Create ()); + NS_TEST_ASSERT (p != 0); + derived = 0; + derived = p->GetAttribute ("TestPtr"); + NS_TEST_ASSERT (derived != 0); + + CHECK_GET_STR (p, "TestInt16", "-2"); + CHECK_GET_PARAM (p, "TestInt16", Integer, -2); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16", String ("-5"))); + CHECK_GET_STR (p, "TestInt16", "-5"); + CHECK_GET_PARAM (p, "TestInt16", Integer, -5); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16", Integer (+2))); + CHECK_GET_STR (p, "TestInt16", "2"); + CHECK_GET_PARAM (p, "TestInt16", Integer, +2); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16", Integer (-32768))); + CHECK_GET_STR (p, "TestInt16", "-32768"); + CHECK_GET_PARAM (p, "TestInt16", Integer, -32768); + + NS_TEST_ASSERT (!p->SetAttribute("TestInt16", Integer (-32769))); + CHECK_GET_STR (p, "TestInt16", "-32768"); + CHECK_GET_PARAM (p, "TestInt16", Integer, -32768); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16", Integer (32767))); + CHECK_GET_STR (p, "TestInt16", "32767"); + CHECK_GET_PARAM (p, "TestInt16", Integer, 32767); + + NS_TEST_ASSERT (!p->SetAttribute("TestInt16", Integer (32768))); + CHECK_GET_STR (p, "TestInt16", "32767"); + CHECK_GET_PARAM (p, "TestInt16", Integer, 32767); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16WithBounds", Integer (10))); + CHECK_GET_STR (p, "TestInt16WithBounds", "10"); + CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, 10); + NS_TEST_ASSERT (!p->SetAttribute("TestInt16WithBounds", Integer (11))); + CHECK_GET_STR (p, "TestInt16WithBounds", "10"); + CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, 10); + + NS_TEST_ASSERT (p->SetAttribute("TestInt16WithBounds", Integer (-5))); + CHECK_GET_STR (p, "TestInt16WithBounds", "-5"); + CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, -5); + NS_TEST_ASSERT (!p->SetAttribute("TestInt16WithBounds", Integer (-6))); + CHECK_GET_STR (p, "TestInt16WithBounds", "-5"); + CHECK_GET_PARAM (p, "TestInt16WithBounds", Integer, -5); + + CHECK_GET_STR (p, "TestInt16SetGet", "6"); + CHECK_GET_PARAM (p, "TestInt16SetGet", Integer, 6); + NS_TEST_ASSERT (p->SetAttribute("TestInt16SetGet", Integer (0))); + CHECK_GET_STR (p, "TestInt16SetGet", "0"); + CHECK_GET_PARAM (p, "TestInt16SetGet", Integer, 0); + + CHECK_GET_STR (p, "TestUint8", "1"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 1); + NS_TEST_ASSERT (p->SetAttribute("TestUint8", Uinteger (0))); + CHECK_GET_STR (p, "TestUint8", "0"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 0); + NS_TEST_ASSERT (p->SetAttribute("TestUint8", Uinteger (255))); + CHECK_GET_STR (p, "TestUint8", "255"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255); + NS_TEST_ASSERT (p->SetAttribute("TestUint8", String ("255"))); + CHECK_GET_STR (p, "TestUint8", "255"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255); + NS_TEST_ASSERT (!p->SetAttribute("TestUint8", String ("256"))); + CHECK_GET_STR (p, "TestUint8", "255"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255); + NS_TEST_ASSERT (!p->SetAttribute("TestUint8", String ("-1"))); + CHECK_GET_STR (p, "TestUint8", "255"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255); + NS_TEST_ASSERT (!p->SetAttribute("TestUint8", Uinteger ((uint64_t)-1))); + CHECK_GET_STR (p, "TestUint8", "255"); + CHECK_GET_PARAM (p, "TestUint8", Uinteger, 255); + + CHECK_GET_STR (p, "TestFloat", "-1.1"); + NS_TEST_ASSERT (p->SetAttribute("TestFloat", Double ((float)+2.3))); + CHECK_GET_PARAM (p, "TestFloat", Double, (float)+2.3); + + CHECK_GET_STR (p, "TestEnum", "TestA"); + CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_A); + NS_TEST_ASSERT (p->SetAttribute("TestEnum", Enum (AttributeObjectTest::TEST_C))); + CHECK_GET_STR (p, "TestEnum", "TestC"); + CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_C); + NS_TEST_ASSERT (p->SetAttribute("TestEnum", String ("TestB"))); + CHECK_GET_STR (p, "TestEnum", "TestB"); + CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B); + NS_TEST_ASSERT (!p->SetAttribute("TestEnum", String ("TestD"))); + CHECK_GET_STR (p, "TestEnum", "TestB"); + CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B); + NS_TEST_ASSERT (!p->SetAttribute("TestEnum", Enum (5))); + CHECK_GET_STR (p, "TestEnum", "TestB"); + CHECK_GET_PARAM (p, "TestEnum", Enum, AttributeObjectTest::TEST_B); + + RandomVariable ran = p->GetAttribute ("TestRandom"); + NS_TEST_ASSERT (p->SetAttribute("TestRandom", UniformVariable (0.0, 1.0))); + NS_TEST_ASSERT (p->SetAttribute("TestRandom", ConstantVariable (10.0))); + + { + ObjectVector vector = p->GetAttribute ("TestVector1"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 0); + p->AddToVector1 (); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 0); + vector = p->GetAttribute ("TestVector1"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 1); + Ptr a = vector.Get (0); + NS_TEST_ASSERT_UNEQUAL (a, 0); + p->AddToVector1 (); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 1); + vector = p->GetAttribute ("TestVector1"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 2); + } + + { + ObjectVector vector = p->GetAttribute ("TestVector2"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 0); + p->AddToVector2 (); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 0); + vector = p->GetAttribute ("TestVector2"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 1); + Ptr a = vector.Get (0); + NS_TEST_ASSERT_UNEQUAL (a, 0); + p->AddToVector2 (); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 1); + vector = p->GetAttribute ("TestVector2"); + NS_TEST_ASSERT_EQUAL (vector.GetN (), 2); + } + + NS_TEST_ASSERT (AttributeList::GetGlobal ()->Set ("AttributeObjectTest::TestBoolName", String ("true"))); + p = CreateObjectWith (); + Boolean boolV = p->GetAttribute ("TestBoolName"); + NS_TEST_ASSERT_EQUAL (boolV, Boolean (true)); + + NS_TEST_ASSERT (AttributeList::GetGlobal ()->Set ("AttributeObjectTest::TestBoolName", String ("false"))); + p = CreateObjectWith (); + boolV = p->GetAttribute ("TestBoolName"); + NS_TEST_ASSERT_EQUAL (boolV, Boolean (false)); + + Integer i = p->GetAttribute ("IntegerTraceSource1"); + NS_TEST_ASSERT_EQUAL (i.Get (), -2); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (+5))); + i = p->GetAttribute ("IntegerTraceSource1"); + NS_TEST_ASSERT_EQUAL (i.Get (), +5); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (127))); + NS_TEST_ASSERT (!p->SetAttribute ("IntegerTraceSource1", Integer (128))); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (-128))); + NS_TEST_ASSERT (!p->SetAttribute ("IntegerTraceSource1", Integer (-129))); + + i = p->GetAttribute ("IntegerTraceSource2"); + NS_TEST_ASSERT_EQUAL (i.Get (), -2); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource2", Integer (+5))); + i = p->GetAttribute ("IntegerTraceSource2"); + NS_TEST_ASSERT_EQUAL (i.Get (), +5); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource2", Integer (127))); + NS_TEST_ASSERT (!p->SetAttribute ("IntegerTraceSource2", Integer (128))); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource2", Integer (-128))); + NS_TEST_ASSERT (!p->SetAttribute ("IntegerTraceSource2", Integer (-129))); + + m_got1 = -2; + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (-1))); + NS_TEST_ASSERT (p->TraceSourceConnect ("Source1", MakeCallback (&AttributeTest::NotifySource1, this))); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (0))); + NS_TEST_ASSERT_EQUAL (m_got1, 0); + NS_TEST_ASSERT (p->TraceSourceDisconnect ("Source1", MakeCallback (&AttributeTest::NotifySource1, this))); + NS_TEST_ASSERT (p->SetAttribute ("IntegerTraceSource1", Integer (1))); + NS_TEST_ASSERT_EQUAL (m_got1, 0); + + m_got2 = 4.3; + p->InvokeCb (1.0, -5, 0.0); + NS_TEST_ASSERT_EQUAL (m_got2, 4.3); + NS_TEST_ASSERT (p->TraceSourceConnect ("Source2", MakeCallback (&AttributeTest::NotifySource2, this))); + NS_TEST_ASSERT_EQUAL (m_got2, 4.3); + p->InvokeCb (1.0, -5, 0.0); + NS_TEST_ASSERT_EQUAL (m_got2, 1.0); + NS_TEST_ASSERT (p->TraceSourceDisconnect ("Source2", MakeCallback (&AttributeTest::NotifySource2, this))); + p->InvokeCb (-1.0, -5, 0.0); + NS_TEST_ASSERT_EQUAL (m_got2, 1.0); + + NS_TEST_ASSERT (p->TraceSourceConnect ("ValueSource", MakeCallback (&AttributeTest::NotifySourceValue, this))); + + + + return result; +} + + + +static AttributeTest g_parameterTest; + +} // namespace ns3 + + +#endif /* RUN_SELF_TESTS */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/attribute.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/attribute.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,171 @@ +#include "attribute.h" +#include "log.h" +#include "fatal-error.h" +#include + +NS_LOG_COMPONENT_DEFINE ("AttributeValue"); + +namespace ns3 { + +AttributeValue::AttributeValue () + : m_count (1) +{} +AttributeValue::AttributeValue (const AttributeValue &o) + : m_count (1) +{} +AttributeValue & +AttributeValue::operator = (const AttributeValue &o) +{ + return *this; +} +AttributeValue::~AttributeValue () +{} + +/*************************************************************** + * Big interesting warning. + * ------------------------ + * + * One might wonder why we re-implement a smart pointer below + * in the Attribute class. This is a very good question and the answer + * is unfortunately pretty complicated. + * + * 1) We could have requested the user to use Ptr and save us + * a lot of pain. This, however, does not work because our smart + * pointer needs a special constructor which can be used to convert + * objects of type Ptr into a PtrValue to hold the pointer. + * + * 2) We could have made the m_value member variable below a Ptr + * rather than store a raw pointer. This, however, does not work + * because this would mean that the constructor Attribute (AttributeValue *) + * should be morphed into Attribute (Ptr) which, unfortunately, + * would conflict with the template constructor Attribute (Ptr)... + * + * This is definitely not fun. + */ +Attribute::Attribute () + : m_value (0) +{} +Attribute::Attribute (const Attribute &o) + : m_value (o.m_value) +{ + if (m_value != 0) + { + m_value->m_count++; + NS_LOG_DEBUG ("this="< checker) const = 0; + virtual bool DeserializeFromString (std::string value, Ptr checker) = 0; +private: + friend class Attribute; + uint32_t m_count; +}; + +class Attribute +{ +public: + Attribute (); + Attribute (const Attribute &o); + Attribute &operator = (const Attribute &o); + ~Attribute (); + + Attribute Copy (void) const; + std::string SerializeToString (Ptr checker) const; + bool DeserializeFromString (std::string value, Ptr checker); + + template + static Attribute Create (void); + template + static Attribute Create (T1 a1); + + template + T DynCast (void) const; + + template + Attribute (Ptr pointer); + template + operator Ptr (); + +private: + Attribute (AttributeValue *value); + AttributeValue *m_value; +}; + +class AttributeAccessor : public ObjectBase +{ +public: + AttributeAccessor (); + void Ref (void) const; + void Unref (void) const; + virtual ~AttributeAccessor (); + + /** + * \param object the object instance to set the value in + * \param value the value to set + * \returns true if the value is valid and it could be set + * successfully, false otherwise. + */ + virtual bool Set (ObjectBase * object, Attribute value) const = 0; + virtual bool Get (const ObjectBase * object, Attribute value) const = 0; +private: + mutable uint32_t m_count; +}; + +class AttributeChecker : public ObjectBase +{ +public: + AttributeChecker (); + void Ref (void) const; + void Unref (void) const; + virtual ~AttributeChecker (); + virtual bool Check (Attribute value) const = 0; +private: + mutable uint32_t m_count; +}; + +template +Ptr +MakeSimpleAttributeChecker (void); + +template +Ptr +MakePtrAccessor (Ptr T::*memberVariable); + +template +Ptr +MakePtrAccessor (void (T::*setter) (Ptr)); +template +Ptr +MakePtrAccessor (Ptr (T::*getter) (void) const); + + +class PtrChecker : public AttributeChecker {}; + +template +Ptr MakePtrChecker (void); + + + +} // namespace ns3 + +namespace ns3 { + +/******************************************************** + * The class used to access the pointer stored in a + * PtrValue AttributeValue instance. + ********************************************************/ + +class PtrValueBase : public AttributeValue +{ +public: + virtual ObjectBase *PeekObjectBase (void) const = 0; + virtual bool SetObjectBase (ObjectBase *object) = 0; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); +}; + +} // namespace ns3 + +/******************************************************** + * Store the content of a Ptr in a AttributeValue + ********************************************************/ + +namespace { + +template +class PtrValue : public ns3::PtrValueBase +{ +public: + PtrValue (ns3::Ptr pointer) + : m_pointer (pointer) {} + + virtual ns3::ObjectBase *PeekObjectBase (void) const { + return PeekPointer (m_pointer); + } + virtual bool SetObjectBase (ns3::ObjectBase *object) { + T *ptr = dynamic_cast (object); + if (ptr == 0) + { + return false; + } + m_pointer = ptr; + return true; + } + virtual ns3::Attribute Copy (void) const { + return ns3::Attribute::Create > (*this); + } +private: + ns3::Ptr m_pointer; +}; + +template +class APtrChecker : public ns3::PtrChecker +{ + virtual bool Check (ns3::Attribute val) const { + const ns3::PtrValueBase *value = val.DynCast (); + if (value == 0) + { + return false; + } + if (value->PeekObjectBase () == 0) + { + return true; + } + T *ptr = dynamic_cast (value->PeekObjectBase ()); + if (ptr == 0) + { + return false; + } + return true; + } +}; + +/******************************************************** + * The Accessor associated to + * PtrValue + ********************************************************/ + +template +class PtrAccessor : public ns3::AttributeAccessor +{ +public: + virtual ~PtrAccessor () {} + virtual bool Set (ns3::ObjectBase * object, ns3::Attribute val) const { + T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + const ns3::PtrValueBase *value = val.DynCast (); + if (value == 0) + { + return false; + } + ns3::Ptr ptr = dynamic_cast (value->PeekObjectBase ()); + if (ptr == 0) + { + return false; + } + DoSet (obj, ptr); + return true; + } + virtual bool Get (const ns3::ObjectBase * object, ns3::Attribute val) const { + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + ns3::PtrValueBase *value = val.DynCast (); + if (value == 0) + { + return false; + } + return value->SetObjectBase (PeekPointer (DoGet (obj))); + } +private: + virtual void DoSet (T *object, ns3::Ptr value) const = 0; + virtual ns3::Ptr DoGet (const T *object) const = 0; +}; + +} // anonymous namespace + +/******************************************************** + * The implementation of the Attribute + * class template methods. + ********************************************************/ + +namespace ns3 { + +template +Attribute +Attribute::Create (void) +{ + return Attribute (new T ()); +} +template +Attribute +Attribute::Create (T1 a1) +{ + return Attribute (new T (a1)); +} + +template +T +Attribute::DynCast (void) const +{ + return dynamic_cast (m_value); +} + +template +Attribute::Attribute (Ptr pointer) + : m_value (new PtrValue (pointer)) +{} +template +Attribute::operator Ptr () +{ + PtrValueBase *value = DynCast (); + if (value == 0) + { + return 0; + } + ObjectBase *objectBase = value->PeekObjectBase (); + T *obj = dynamic_cast (objectBase); + if (obj == 0) + { + return 0; + } + return obj; +} + + + +template +Ptr +MakePtrAccessor (Ptr T::*memberVariable) +{ + struct MemberVariable : public PtrAccessor + { + Ptr T::*m_memberVariable; + virtual MemberVariable *Copy (void) const { + return new MemberVariable (*this); + } + virtual void DoSet (T *object, Ptr value) const { + (object->*m_memberVariable) = value; + } + virtual Ptr DoGet (const T *object) const { + return object->*m_memberVariable; + } + } *spec = new MemberVariable (); + spec->m_memberVariable = memberVariable; + return Ptr (spec, false); +} + +template +Ptr +MakePtrAccessor (void (T::*setter) (Ptr)) +{ + struct MemberMethod : public PtrAccessor + { + void (T::*m_setter) (Ptr); + virtual MemberMethod *Copy (void) const { + return new MemberMethod (*this); + } + virtual void DoSet (T *object, Ptr value) const { + (object->*m_setter) (value); + } + virtual Ptr DoGet (const T *object) const { + return 0; + //return (object->*m_getter) (); + } + } *spec = new MemberMethod (); + spec->m_setter = setter; + return Ptr (spec, false); +} + +template +Ptr +MakePtrAccessor (Ptr (T::*getter) (void) const) +{ + struct MemberMethod : public PtrAccessor + { + void (T::*m_getter) (Ptr); + virtual MemberMethod *Copy (void) const { + return new MemberMethod (*this); + } + virtual void DoSet (T *object, Ptr value) const { + //(object->*m_setter) (value); + } + virtual Ptr DoGet (const T *object) const { + return (object->*m_getter) (); + } + } *spec = new MemberMethod (); + spec->m_getter = getter; + return Ptr (spec, false); +} + + +template +Ptr +MakePtrChecker (void) +{ + return Create > (); +} + +template +Ptr +MakeSimpleAttributeChecker (void) +{ + struct SimpleAttributeChecker : public BASE + { + virtual bool Check (Attribute value) const { + return value.DynCast () != 0; + } + } *checker = new SimpleAttributeChecker (); + return Ptr (checker, false); +} + + +} // namespace ns3 + +#endif /* ATTRIBUTE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/boolean.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/boolean.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,66 @@ +#include "boolean.h" +#include "fatal-error.h" + +namespace ns3 { + +Boolean::Boolean () + : m_value (false) +{} +Boolean::Boolean (bool value) + : m_value (value) +{} +void +Boolean::Set (bool value) +{ + m_value = value; +} +bool +Boolean::Get (void) const +{ + return m_value; +} +Boolean::operator bool () const +{ + return m_value; +} + +std::ostream & operator << (std::ostream &os, const Boolean &value) +{ + if (value.Get ()) + { + os << "true"; + } + else + { + os << "false"; + } + return os; +} +std::istream & operator >> (std::istream &is, Boolean &value) +{ + std::string v; + is >> v; + if (v == "true" || + v == "1" || + v == "t") + { + value.Set (true); + } + else if (v == "false" || + v == "0" || + v == "f") + { + value.Set (false); + } + else + { + is.setstate (std::ios_base::badbit); + } + return is; +} + +ATTRIBUTE_CONVERTER_IMPLEMENT (Boolean); +ATTRIBUTE_VALUE_IMPLEMENT (Boolean); +ATTRIBUTE_CHECKER_IMPLEMENT (Boolean); + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/boolean.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/boolean.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,33 @@ +#ifndef BOOLEAN_H +#define BOOLEAN_H + +#include "attribute.h" +#include "attribute-helper.h" + +namespace ns3 { + +class Boolean +{ +public: + Boolean (); + Boolean (bool value); + void Set (bool value); + bool Get (void) const; + + operator bool () const; + + ATTRIBUTE_CONVERTER_DEFINE (Boolean); +private: + bool m_value; +}; + +std::ostream & operator << (std::ostream &os, const Boolean &value); +std::istream & operator >> (std::istream &is, Boolean &value); + +ATTRIBUTE_VALUE_DEFINE (Boolean); +ATTRIBUTE_CHECKER_DEFINE (Boolean); +ATTRIBUTE_ACCESSOR_DEFINE (Boolean); + +} // namespace ns3 + +#endif /* BOOLEAN_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/callback.h --- a/src/core/callback.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/callback.h Wed Feb 27 22:19:39 2008 +0100 @@ -26,6 +26,7 @@ #include "fatal-error.h" #include "empty.h" #include "type-traits.h" +#include "object-base.h" namespace ns3 { @@ -70,7 +71,8 @@ } }; -class CallbackImplBase { +class CallbackImplBase : public ObjectBase +{ public: CallbackImplBase () : m_count (1) {} diff -r d64b1561b1c2 -r e667dc0f350e src/core/config.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/config.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,613 @@ +#include "config.h" +#include "singleton.h" +#include "object.h" +#include "global-value.h" +#include "object-vector.h" +#include "log.h" +#include + +NS_LOG_COMPONENT_DEFINE ("Config"); + +namespace ns3 { + +class ArrayMatcher +{ +public: + ArrayMatcher (std::string element); + bool Matches (uint32_t i) const; +private: + bool StringToUint32 (std::string str, uint32_t *value) const; + std::string m_element; +}; + + +ArrayMatcher::ArrayMatcher (std::string element) + : m_element (element) +{} +bool +ArrayMatcher::Matches (uint32_t i) const +{ + if (m_element == "*") + { + NS_LOG_DEBUG ("Array "< leftBracket && dash < rightBracket) + { + std::string lowerBound = m_element.substr (leftBracket + 1, dash - (leftBracket + 1)); + std::string upperBound = m_element.substr (dash + 1, rightBracket - (dash + 1)); + uint32_t min; + uint32_t max; + if (StringToUint32 (lowerBound, &min) && + StringToUint32 (upperBound, &max) && + i >= min && i <= max) + { + NS_LOG_DEBUG ("Array "<> (*value); + return !iss.bad () && !iss.fail (); +} + + +class Resolver +{ +public: + Resolver (std::string path); + virtual ~Resolver (); + + void Resolve (Ptr root); +private: + void DoResolve (std::string path, Ptr root); + void DoArrayResolve (std::string path, const ObjectVector &vector); + void DoResolveOne (Ptr object, std::string name); + std::string GetResolvedPath (std::string name) const; + virtual void DoOne (Ptr object, std::string name) = 0; + std::vector m_workStack; + std::string m_path; +}; + +Resolver::Resolver (std::string path) + : m_path (path) +{} +Resolver::~Resolver () +{} + +void +Resolver::Resolve (Ptr root) +{ + DoResolve (m_path, root); +} + +std::string +Resolver::GetResolvedPath (std::string name) const +{ + std::string fullPath = ""; + for (std::vector::const_iterator i = m_workStack.begin (); i != m_workStack.end (); i++) + { + fullPath += "/" + *i; + } + fullPath += "/" + name; + return fullPath; +} + +void +Resolver::DoResolveOne (Ptr object, std::string name) +{ + NS_LOG_DEBUG ("resolved="< root) +{ + NS_ASSERT (path != ""); + std::string::size_type pos = path.find ("/"); + if (pos != 0) + { + NS_FATAL_ERROR ("path does not start with a \"/\": \""< object = root->GetObject (tid); + if (object == 0) + { + NS_LOG_DEBUG ("GetObject ("<GetRealTypeId (); + struct TypeId::AttributeInfo info; + if (!tid.LookupAttributeByName (item, &info)) + { + NS_LOG_DEBUG ("Requested item="< (PeekPointer (info.checker)); + if (ptr != 0) + { + NS_LOG_DEBUG ("GetAttribute(ptr)="<. We really need to fix this by thinking seriously about our + // object hierarchy. + Ptr object = root->GetAttribute (item); + if (object == 0) + { + NS_LOG_ERROR ("Requested object name=\""< (PeekPointer (info.checker)); + if (vectorChecker != 0) + { + NS_LOG_DEBUG ("GetAttribute(vector)="<GetAttribute (item); + m_workStack.push_back (item); + DoArrayResolve (pathLeft, vector); + m_workStack.pop_back (); + } + // this could be anything else and we don't know what to do with it. + // So, we just ignore it. + } +} + +void +Resolver::DoArrayResolve (std::string path, const ObjectVector &vector) +{ + NS_ASSERT (path != ""); + std::string::size_type pos = path.find ("/"); + if (pos != 0) + { + NS_FATAL_ERROR ("path does not start with a \"/\": \""< obj); + void UnregisterRootNamespaceObject (Ptr obj); + +private: + typedef std::vector > Roots; + Roots m_roots; +}; + +void +ConfigImpl::Set (std::string path, Attribute value) +{ + class SetResolver : public Resolver + { + public: + SetResolver (std::string path, Attribute value) + : Resolver (path), + m_value (value) {} + private: + virtual void DoOne (Ptr object, std::string name) { + object->SetAttribute (name, m_value); + } + Attribute m_value; + } resolver = SetResolver (path, value); + for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) + { + resolver.Resolve (*i); + } +} +void +ConfigImpl::Connect (std::string path, const CallbackBase &cb) +{ + class ConnectResolver : public Resolver + { + public: + ConnectResolver (std::string path, const CallbackBase &cb) + : Resolver (path), + m_cb (cb) {} + private: + virtual void DoOne (Ptr object, std::string name) { + object->TraceSourceConnect (name, m_cb); + } + CallbackBase m_cb; + } resolver = ConnectResolver (path, cb); + for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) + { + resolver.Resolve (*i); + } +} +void +ConfigImpl::Disconnect (std::string path, const CallbackBase &cb) +{ + class DisconnectResolver : public Resolver + { + public: + DisconnectResolver (std::string path, const CallbackBase &cb) + : Resolver (path), + m_cb (cb) {} + private: + virtual void DoOne (Ptr object, std::string name) { + object->TraceSourceDisconnect (name, m_cb); + } + CallbackBase m_cb; + } resolver = DisconnectResolver (path, cb); + for (Roots::const_iterator i = m_roots.begin (); i != m_roots.end (); i++) + { + resolver.Resolve (*i); + } +} +void +ConfigImpl::RegisterRootNamespaceObject (Ptr obj) +{ + m_roots.push_back (obj); +} + +void +ConfigImpl::UnregisterRootNamespaceObject (Ptr obj) +{ + for (std::vector >::iterator i = m_roots.begin (); i != m_roots.end (); i++) + { + if (*i == obj) + { + m_roots.erase (i); + return; + } + } +} + + +namespace Config { + +void Set (std::string path, Attribute value) +{ + Singleton::Get ()->Set (path, value); +} +void SetDefault (std::string name, Attribute value) +{ + AttributeList::GetGlobal ()->Set (name, value); +} +void SetGlobal (std::string name, Attribute value) +{ + GlobalValue::Bind (name, value); +} +void Connect (std::string path, const CallbackBase &cb) +{ + Singleton::Get ()->Connect (path, cb); +} +void Disconnect (std::string path, const CallbackBase &cb) +{ + Singleton::Get ()->Disconnect (path, cb); +} + +void RegisterRootNamespaceObject (Ptr obj) +{ + Singleton::Get ()->RegisterRootNamespaceObject (obj); +} + +void Unregister (Ptr obj) +{ + Singleton::Get ()->UnregisterRootNamespaceObject (obj); +} + +} // namespace Config + +} // namespace ns3 + +#ifdef RUN_SELF_TESTS + +#include "test.h" +#include "integer.h" + +namespace ns3 { + +class MyNode : public Object +{ +public: + static TypeId GetTypeId (void); + + void AddNodeA (Ptr a); + void AddNodeB (Ptr b); + + void SetNodeA (Ptr a); + void SetNodeB (Ptr b); + + int8_t GetA (void) const; + int8_t GetB (void) const; + +private: + std::vector > m_nodesA; + std::vector > m_nodesB; + Ptr m_nodeA; + Ptr m_nodeB; + int8_t m_a; + int8_t m_b; +}; + +TypeId MyNode::GetTypeId (void) +{ + static TypeId tid = TypeId ("MyNode") + .SetParent () + .AddAttribute ("NodesA", "", + ObjectVector (), + MakeObjectVectorAccessor (&MyNode::m_nodesA), + MakeObjectVectorChecker ()) + .AddAttribute ("NodesB", "", + ObjectVector (), + MakeObjectVectorAccessor (&MyNode::m_nodesB), + MakeObjectVectorChecker ()) + .AddAttribute ("NodeA", "", + Ptr (0), + MakePtrAccessor (&MyNode::m_nodeA), + MakePtrChecker ()) + .AddAttribute ("NodeB", "", + Ptr (0), + MakePtrAccessor (&MyNode::m_nodeB), + MakePtrChecker ()) + .AddAttribute ("A", "", + Integer (10), + MakeIntegerAccessor (&MyNode::m_a), + MakeIntegerChecker ()) + .AddAttribute ("B", "", + Integer (9), + MakeIntegerAccessor (&MyNode::m_b), + MakeIntegerChecker ()) + ; + return tid; +} + +void +MyNode::SetNodeA (Ptr a) +{ + m_nodeA = a; +} +void +MyNode::SetNodeB (Ptr b) +{ + m_nodeB = b; +} +void +MyNode::AddNodeA (Ptr a) +{ + m_nodesA.push_back (a); +} +void +MyNode::AddNodeB (Ptr b) +{ + m_nodesB.push_back (b); +} +int8_t +MyNode::GetA (void) const +{ + return m_a; +} +int8_t +MyNode::GetB (void) const +{ + return m_b; +} + + +class ConfigTest : public Test +{ +public: + ConfigTest (); + virtual bool RunTests (void); +}; + +static ConfigTest g_configTestUnique; + +ConfigTest::ConfigTest () + : Test ("Config") +{} + +bool +ConfigTest::RunTests (void) +{ + bool result = true; + + Ptr root = CreateObject (); + Config::RegisterRootNamespaceObject (root); + Config::Set ("/A", Integer (1)); + Config::Set ("/B", Integer (-1)); + Integer v = root->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 1); + v = root->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), -1); + + Ptr a = CreateObject (); + root->SetNodeA (a); + Config::Set ("/NodeA/A", Integer (2)); + Config::Set ("/NodeA/B", Integer (-2)); + v = a->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 2); + v = a->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), -2); + Config::Set ("/NodeB/A", Integer (3)); + Config::Set ("/NodeB/B", Integer (-3)); + v = a->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 2); + v = a->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), -2); + + Ptr b = CreateObject (); + a->SetNodeB (b); + Config::Set ("/NodeA/NodeB/A", Integer (4)); + Config::Set ("/NodeA/NodeB/B", Integer (-4)); + v = b->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 4); + v = b->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), -4); + + Ptr c = CreateObject (); + root->SetNodeB (c); + Config::Set ("/NodeB/A", Integer (5)); + Config::Set ("/NodeB/B", Integer (-5)); + v = c->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 5); + v = c->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), -5); + + + Ptr d0 = CreateObject (); + Ptr d1 = CreateObject (); + Ptr d2 = CreateObject (); + Ptr d3 = CreateObject (); + b->AddNodeB (d0); + b->AddNodeB (d1); + b->AddNodeB (d2); + b->AddNodeB (d3); + Config::Set ("/NodeA/NodeB/NodesB/0/A", Integer (-11)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -11); + v = d0->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), 9); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), 10); + v = d1->GetAttribute ("B"); + NS_TEST_ASSERT_EQUAL (v.Get (), 9); + Config::Set ("/NodeA/NodeB/NodesB/0|1/A", Integer (-12)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -12); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -12); + Config::Set ("/NodeA/NodeB/NodesB/|0|1|/A", Integer (-13)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -13); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -13); + Config::Set ("/NodeA/NodeB/NodesB/[0-2]/A", Integer (-14)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -14); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -14); + v = d2->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -14); + Config::Set ("/NodeA/NodeB/NodesB/[1-3]/A", Integer (-15)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -14); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -15); + v = d2->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -15); + v = d3->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -15); + Config::Set ("/NodeA/NodeB/NodesB/[0-1]|3/A", Integer (-16)); + v = d0->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -16); + v = d1->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -16); + v = d2->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -15); + v = d3->GetAttribute ("A"); + NS_TEST_ASSERT_EQUAL (v.Get (), -16); + + + + return result; +} + +} // namespace ns3 + + +#endif /* RUN_SELF_TEST */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/config.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,25 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include "attribute.h" +#include "ptr.h" +#include "object.h" +#include + +namespace ns3 { + +namespace Config { + +void Set (std::string path, Attribute value); +void SetDefault (std::string name, Attribute value); +void SetGlobal (std::string name, Attribute value); +void Connect (std::string path, const CallbackBase &cb); +void Disconnect (std::string path, const CallbackBase &cb); + +void RegisterRootNamespaceObject (Ptr obj); + +} // namespace Config + +} // namespace ns3 + +#endif /* CONFIG_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/double.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/double.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,64 @@ +#include "double.h" +#include "object.h" +#include + +namespace ns3 { + +Double::Double () +{} +Double::Double (double value) + : m_value (value) +{} +void +Double::Set (double value) +{ + m_value = value; +} +double +Double::Get (void) const +{ + return m_value; +} +Double::operator double () const +{ + return m_value; +} +std::ostream & operator << (std::ostream &os, const Double &value) +{ + os << value.Get (); + return os; +} +std::istream & operator >> (std::istream &is, Double &value) +{ + double v; + is >> v; + value.Set (v); + return is; +} + +ATTRIBUTE_VALUE_IMPLEMENT (Double); + ATTRIBUTE_CONVERTER_IMPLEMENT (Double); + +Ptr MakeDoubleChecker (double min, double max) +{ + struct Checker : public AttributeChecker + { + Checker (double minValue, double maxValue) + : m_minValue (minValue), + m_maxValue (maxValue) {} + virtual bool Check (Attribute value) const { + const DoubleValue *v = value.DynCast (); + if (v == 0) + { + return false; + } + return v->Get () >= m_minValue && v->Get () <= m_maxValue; + } + double m_minValue; + double m_maxValue; + } *checker = new Checker (min, max); + return Ptr (checker, false); +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/double.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/double.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,62 @@ +#ifndef FP_VALUE_H +#define FP_VALUE_H + +#include "attribute.h" +#include "attribute-helper.h" +#include + +namespace ns3 { + +class Double +{ +public: + Double (); + Double (double value); + + void Set (double value); + double Get (void) const; + + operator double () const; + + ATTRIBUTE_CONVERTER_DEFINE (Double); +private: + double m_value; +}; + +std::ostream & operator << (std::ostream &os, const Double &value); +std::istream & operator >> (std::istream &is, Double &value); + +ATTRIBUTE_VALUE_DEFINE (Double); +ATTRIBUTE_ACCESSOR_DEFINE (Double); + +template +Ptr MakeDoubleChecker (void); + +template +Ptr MakeDoubleChecker (double min); + +Ptr MakeDoubleChecker (double min, double max); + + +} // namespace ns3 + +namespace ns3 { + +template +Ptr MakeDoubleChecker (void) +{ + return MakeDoubleChecker (-std::numeric_limits::max (), + std::numeric_limits::max ()); +} + +template +Ptr MakeDoubleChecker (double min) +{ + return MakeDoubleChecker (min, + std::numeric_limits::max ()); +} + +} // namespace ns3 + + +#endif /* FP_VALUE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/enum.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/enum.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,182 @@ +#include "enum.h" +#include "fatal-error.h" +#include + +namespace ns3 { + + +Enum::Enum (int v) + : m_v (v) +{} +void +Enum::Set (int v) +{ + m_v = v; +} +int +Enum::Get (void) const +{ + return m_v; +} + +Attribute +Enum::Copy (void) const +{ + return Attribute::Create (*this); +} +std::string +Enum::SerializeToString (Ptr checker) const +{ + const EnumChecker *p = dynamic_cast (PeekPointer (checker)); + NS_ASSERT (p != 0); + for (EnumChecker::ValueSet::const_iterator i = p->m_valueSet.begin (); i != p->m_valueSet.end (); i++) + { + if (i->first == m_v) + { + return i->second; + } + } + + NS_FATAL_ERROR ("The user has set an invalid C++ value in this Enum"); + // quiet compiler. + return ""; +} +bool +Enum::DeserializeFromString (std::string value, Ptr checker) +{ + const EnumChecker *p = dynamic_cast (PeekPointer (checker)); + NS_ASSERT (p != 0); + for (EnumChecker::ValueSet::const_iterator i = p->m_valueSet.begin (); i != p->m_valueSet.end (); i++) + { + if (i->second == value) + { + m_v = i->first; + return true; + } + } + return false; +} + +Enum::Enum (Attribute value) +{ + const Enum *v = value.DynCast (); + if (v == 0) + { + NS_FATAL_ERROR ("assigning non-Enum value to Enum value."); + } + m_v = v->m_v; +} +Enum::operator Attribute () const +{ + return Attribute::Create (*this); +} + + + +EnumChecker::EnumChecker () +{} + +void +EnumChecker::AddDefault (int v, std::string name) +{ + m_valueSet.push_front (std::make_pair (v, name)); +} +void +EnumChecker::Add (int v, std::string name) +{ + m_valueSet.push_back (std::make_pair (v, name)); +} +bool +EnumChecker::Check (Attribute value) const +{ + const Enum *p = value.DynCast (); + if (p == 0) + { + return false; + } + for (ValueSet::const_iterator i = m_valueSet.begin (); i != m_valueSet.end (); i++) + { + if (i->first == p->Get ()) + { + return true; + } + } + return false; +} + +Ptr +MakeEnumChecker (int v1, std::string n1, + int v2, std::string n2, + int v3, std::string n3, + int v4, std::string n4, + int v5, std::string n5, + int v6, std::string n6, + int v7, std::string n7, + int v8, std::string n8, + int v9, std::string n9, + int v10, std::string n10, + int v11, std::string n11, + int v12, std::string n12) +{ + Ptr checker = Create (); + checker->AddDefault (v1, n1); + if (n2 == "") + { + return checker; + } + checker->Add (v2, n2); + if (n3 == "") + { + return checker; + } + checker->Add (v3, n3); + if (n4 == "") + { + return checker; + } + checker->Add (v4, n4); + if (n5 == "") + { + return checker; + } + checker->Add (v5, n5); + if (n6 == "") + { + return checker; + } + checker->Add (v6, n6); + if (n7 == "") + { + return checker; + } + checker->Add (v7, n7); + if (n8 == "") + { + return checker; + } + checker->Add (v8, n8); + if (n9 == "") + { + return checker; + } + checker->Add (v9, n9); + if (n10 == "") + { + return checker; + } + checker->Add (v10, n10); + if (n11 == "") + { + return checker; + } + checker->Add (v11, n11); + if (n12 == "") + { + return checker; + } + checker->Add (v12, n12); + return checker; +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/enum.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/enum.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,81 @@ +#ifndef ENUM_VALUE_H +#define ENUM_VALUE_H + +#include "attribute.h" +#include "attribute-accessor-helper.h" +#include + +namespace ns3 { + +class Enum : public AttributeValue +{ +public: + Enum (int v); + void Set (int v); + int Get (void) const; + + virtual Attribute Copy (void) const; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); + + Enum (Attribute value); + operator Attribute () const; +private: + int m_v; +}; + +class EnumChecker : public AttributeChecker +{ +public: + EnumChecker (); + + void AddDefault (int v, std::string name); + void Add (int v, std::string name); + + virtual bool Check (Attribute value) const; + +private: + friend class Enum; + typedef std::list > ValueSet; + ValueSet m_valueSet; +}; + +template +Ptr MakeEnumAccessor (T1 a1); + +template +Ptr MakeEnumAccessor (T1 a1, T2 a2); + +Ptr MakeEnumChecker (int v1, std::string n1, + int v2 = 0, std::string n2 = "", + int v3 = 0, std::string n3 = "", + int v4 = 0, std::string n4 = "", + int v5 = 0, std::string n5 = "", + int v6 = 0, std::string n6 = "", + int v7 = 0, std::string n7 = "", + int v8 = 0, std::string n8 = "", + int v9 = 0, std::string n9 = "", + int v10 = 0, std::string n10 = "", + int v11 = 0, std::string n11 = "", + int v12 = 0, std::string n12 = ""); + + +} // namespace ns3 + +namespace ns3 { + +template +Ptr MakeEnumAccessor (T1 a1) +{ + return MakeAccessorHelper (a1); +} + +template +Ptr MakeEnumAccessor (T1 a1, T2 a2) +{ + return MakeAccessorHelper (a1, a2); +} + +} // namespace ns3 + +#endif /* ENUM_VALUE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/global-value.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/global-value.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,125 @@ +#include "global-value.h" +#include "fatal-error.h" +#include "attribute.h" + +namespace ns3 { + +GlobalValue::GlobalValue (std::string name, std::string help, + Attribute initialValue, + Ptr checker) + : m_name (name), + m_help (help), + m_initialValue (initialValue), + m_checker (checker) +{ + if (m_checker == 0) + { + NS_FATAL_ERROR ("Checker should no be zero."); + } + GetVector ()->push_back (this); +} + +std::string +GlobalValue::GetName (void) const +{ + return m_name; +} +std::string +GlobalValue::GetHelp (void) const +{ + return m_help; +} +Attribute +GlobalValue::GetValue (void) const +{ + return m_initialValue; +} +Ptr +GlobalValue::GetChecker (void) const +{ + return m_checker; +} + +void +GlobalValue::SetValue (Attribute value) +{ + if (!m_checker->Check (value)) + { + NS_FATAL_ERROR ("Invalid new value."); + } + m_initialValue = value; +} + +void +GlobalValue::Bind (std::string name, Attribute value) +{ + for (Iterator i = Begin (); i != End (); i++) + { + if ((*i)->GetName () == name) + { + (*i)->SetValue (value); + return; + } + } +} +GlobalValue::Iterator +GlobalValue::Begin (void) +{ + return GetVector ()->begin (); +} +GlobalValue::Iterator +GlobalValue::End (void) +{ + return GetVector ()->end (); +} +GlobalValue::Vector * +GlobalValue::GetVector (void) +{ + static Vector vector; + return &vector; +} + +} // namespace ns3 + +#ifdef RUN_SELF_TESTS + +#include "test.h" +#include "uinteger.h" + +namespace { + +static ns3::GlobalValue g_uint = ns3::GlobalValue ("TestUint", "help text", + ns3::Uinteger (10), + ns3::MakeUintegerChecker ()); + +} + +namespace ns3 { + +class GlobalValueTests : public Test +{ +public: + GlobalValueTests (); + virtual bool RunTests (void); +private: +}; + + +GlobalValueTests::GlobalValueTests () + : Test ("GlobalValue") +{} +bool +GlobalValueTests::RunTests (void) +{ + bool result = true; + + NS_TEST_ASSERT_EQUAL (10, Uinteger (g_uint.GetValue ()).Get ()); + + return result; +} + +static GlobalValueTests g_initialValueTests; + +} // namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/global-value.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/global-value.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,43 @@ +#ifndef GLOBAL_VALUE_H +#define GLOBAL_VALUE_H + +#include +#include +#include "ptr.h" +#include "attribute.h" + + +namespace ns3 { + +class GlobalValue +{ + typedef std::vector Vector; +public: + typedef Vector::const_iterator Iterator; + + GlobalValue (std::string name, std::string help, + Attribute initialValue, + Ptr checker); + + std::string GetName (void) const; + std::string GetHelp (void) const; + Attribute GetValue (void) const; + Ptr GetChecker (void) const; + + void SetValue (Attribute value); + + static void Bind (std::string name, Attribute value); + + static Iterator Begin (void); + static Iterator End (void); +private: + static Vector *GetVector (void); + std::string m_name; + std::string m_help; + Attribute m_initialValue; + Ptr m_checker; +}; + +} // namespace ns3 + +#endif /* GLOBAL_VALUE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/integer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/integer.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,70 @@ +#include "integer.h" +#include "fatal-error.h" +#include + +namespace ns3 { + +Integer::Integer (int64_t value) + : m_value (value) +{} +Integer::Integer () + : m_value (0) +{} +void +Integer::Set (int64_t value) +{ + m_value = value; +} +int64_t +Integer::Get (void) const +{ + return m_value; +} + +Integer::operator int64_t () const +{ + return m_value; +} + +ATTRIBUTE_VALUE_IMPLEMENT (Integer); + +std::ostream &operator << (std::ostream &os, const Integer &integer) +{ + os << integer.Get (); + return os; +} +std::istream &operator >> (std::istream &is, Integer &integer) +{ + int64_t v; + is >> v; + integer.Set (v); + return is; +} + +ATTRIBUTE_CONVERTER_IMPLEMENT (Integer); + + +Ptr +MakeIntegerChecker (int64_t min, int64_t max) +{ + struct IntegerChecker : public AttributeChecker + { + IntegerChecker (int64_t minValue, int64_t maxValue) + : m_minValue (minValue), + m_maxValue (maxValue) {} + virtual bool Check (Attribute value) const { + const IntegerValue *v = value.DynCast (); + if (v == 0) + { + return false; + } + return v->Get ().Get () >= m_minValue && v->Get ().Get() <= m_maxValue; + } + int64_t m_minValue; + int64_t m_maxValue; + } *checker = new IntegerChecker (min, max); + return Ptr (checker, false); +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/integer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/integer.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,60 @@ +#ifndef INTEGER_H +#define INTEGER_H + +#include "attribute.h" +#include "attribute-helper.h" +#include + +namespace ns3 { + +class Integer +{ +public: + Integer (int64_t value); + Integer (); + void Set (int64_t value); + int64_t Get (void) const; + + operator int64_t () const; + ATTRIBUTE_CONVERTER_DEFINE (Integer); +private: + int64_t m_value; +}; + +std::ostream &operator << (std::ostream &os, const Integer &integer); +std::istream &operator >> (std::istream &is, Integer &integer); + +ATTRIBUTE_VALUE_DEFINE(Integer); +ATTRIBUTE_ACCESSOR_DEFINE(Integer); + +template +Ptr MakeIntegerChecker (void); + +template +Ptr MakeIntegerChecker (int64_t min); + +Ptr MakeIntegerChecker (int64_t min, int64_t max); + +} // namespace ns3 + +namespace ns3 { + +template +Ptr +MakeIntegerChecker (int64_t min) +{ + return MakeIntegerChecker (min, + std::numeric_limits::max ()); +} + +template +Ptr +MakeIntegerChecker (void) +{ + return MakeIntegerChecker (std::numeric_limits::min (), + std::numeric_limits::max ()); +} + +} // namespace ns3 + +#endif /* INTEGER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-base.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-base.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,3 @@ +#include "object-base.h" + +ns3::ObjectBase::~ObjectBase () {} diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-base.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-base.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,20 @@ +#ifndef OBJECT_BASE_H +#define OBJECT_BASE_H + +namespace ns3 { + +/** + * This base class is really used only to make sure that + * every subclass has RTTI information and that they all + * share a single base class to allow us to make type + * checks across all these types. + */ +class ObjectBase +{ +public: + virtual ~ObjectBase (); +}; + +} // namespace ns3 + +#endif /* OBJECT_BASE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-factory.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-factory.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,43 @@ +#include "object-factory.h" +#include + +namespace ns3 { + +ObjectFactory::ObjectFactory () +{} + +void +ObjectFactory::SetTypeId (TypeId tid) +{ + m_tid = tid; +} +void +ObjectFactory::SetTypeId (std::string tid) +{ + m_tid = TypeId::LookupByName (tid); +} +void +ObjectFactory::SetTypeId (const char *tid) +{ + m_tid = TypeId::LookupByName (tid); +} +void +ObjectFactory::Set (std::string name, Attribute value) +{ + m_parameters.SetWithTid (m_tid, name, value); +} + +TypeId +ObjectFactory::GetTypeId (void) const +{ + return m_tid; +} + +Ptr +ObjectFactory::Create (void) const +{ + Ptr object = m_tid.CreateObject (m_parameters); + return object; +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-factory.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-factory.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,43 @@ +#ifndef OBJECT_FACTORY_H +#define OBJECT_FACTORY_H + +#include "attribute.h" +#include "object.h" + +namespace ns3 { + +class ObjectFactory +{ +public: + ObjectFactory (); + + void SetTypeId (TypeId tid); + void SetTypeId (std::string tid); + void SetTypeId (const char *tid); + void Set (std::string name, Attribute value); + + TypeId GetTypeId (void) const; + + Ptr Create (void) const; + template + Ptr Create (void) const; + +private: + TypeId m_tid; + AttributeList m_parameters; +}; + +} // namespace ns3 + +namespace ns3 { + +template +Ptr +ObjectFactory::Create (void) const +{ + return Create ()->GetObject (); +} + +} // namespace ns3 + +#endif /* OBJECT_FACTORY_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-vector.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-vector.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,110 @@ +#include "object-vector.h" + +namespace ns3 { + +ObjectVector::ObjectVector () +{} + +ObjectVector::Iterator +ObjectVector::Begin (void) const +{ + return m_objects.begin (); +} +ObjectVector::Iterator +ObjectVector::End (void) const +{ + return m_objects.end (); +} +uint32_t +ObjectVector::GetN (void) const +{ + return m_objects.size (); +} +Ptr +ObjectVector::Get (uint32_t i) const +{ + return m_objects[i]; +} + +ObjectVector::ObjectVector (Attribute value) +{ + const ObjectVectorValue *v = value.DynCast (); + if (v == 0) + { + NS_FATAL_ERROR ("Expected value of type ObjectVectorValue."); + } + *this = v->Get (); +} + +ObjectVector::operator Attribute () const +{ + return Attribute::Create (); +} + +ObjectVectorValue::ObjectVectorValue () + : m_vector () +{} + +ObjectVectorValue::ObjectVectorValue (const ObjectVector &vector) + : m_vector (vector) +{} + +ObjectVector +ObjectVectorValue::Get (void) const +{ + return m_vector; +} + +Attribute +ObjectVectorValue::Copy (void) const +{ + return Attribute::Create (*this); +} +std::string +ObjectVectorValue::SerializeToString (Ptr checker) const +{ + // XXX + return ""; +} +bool +ObjectVectorValue::DeserializeFromString (std::string value, Ptr checker) +{ + // XXX ?? Can we implement this correctly ?? I doubt it very much. + return true; +} + +bool +ObjectVectorAccessor::Set (ObjectBase * object, Attribute value) const +{ + // not allowed. + return false; +} +bool +ObjectVectorAccessor::Get (const ObjectBase * object, Attribute value) const +{ + ObjectVectorValue *v = value.DynCast (); + if (v == 0) + { + return false; + } + v->m_vector.m_objects.clear (); + uint32_t n; + bool ok = DoGetN (object, &n); + if (!ok) + { + return false; + } + for (uint32_t i = 0; i < n; i++) + { + Ptr o = DoGet (object, i); + v->m_vector.m_objects.push_back (o); + } + return true; +} +Ptr +MakeObjectVectorChecker (void) +{ + return MakeSimpleAttributeChecker (); +} + +} // name diff -r d64b1561b1c2 -r e667dc0f350e src/core/object-vector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/object-vector.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,155 @@ +#ifndef OBJECT_VECTOR_H +#define OBJECT_VECTOR_H + +#include +#include "object.h" +#include "ptr.h" +#include "attribute.h" + +namespace ns3 { + +class ObjectVector +{ +public: + typedef std::vector >::const_iterator Iterator; + + ObjectVector (); + + Iterator Begin (void) const; + Iterator End (void) const; + uint32_t GetN (void) const; + Ptr Get (uint32_t i) const; + + ObjectVector (Attribute value); + operator Attribute () const; +private: + friend class ObjectVectorAccessor; + std::vector > m_objects; +}; + +template +Ptr +MakeObjectVectorAccessor (U T::*memberVector); + +template +Ptr +MakeObjectVectorAccessor (Ptr (T::*get) (INDEX) const, + INDEX (T::*getN) (void) const); + +template +Ptr +MakeObjectVectorAccessor (INDEX (T::*getN) (void) const, + Ptr (T::*get) (INDEX) const); + + +class ObjectVectorChecker : public AttributeChecker {}; +Ptr MakeObjectVectorChecker (void); + +} // namespace ns3 + +namespace ns3 { + +class ObjectVectorValue : public AttributeValue +{ +public: + ObjectVectorValue (); + ObjectVectorValue (const ObjectVector &vector); + + ObjectVector Get (void) const; + + virtual Attribute Copy (void) const; + virtual std::string SerializeToString (Ptr checker) const; + virtual bool DeserializeFromString (std::string value, Ptr checker); + +private: + friend class ObjectVectorAccessor; + ObjectVector m_vector; +}; + +class ObjectVectorAccessor : public AttributeAccessor +{ +public: + virtual bool Set (ObjectBase * object, Attribute value) const; + virtual bool Get (const ObjectBase * object, Attribute value) const; +private: + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const = 0; + virtual Ptr DoGet (const ObjectBase *object, uint32_t i) const = 0; +}; + +template +Ptr +MakeObjectVectorAccessor (U T::*memberVector) +{ + struct MemberStdContainer : public ObjectVectorAccessor + { + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const { + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + *n = (obj->*m_memberVector).size (); + return true; + } + virtual Ptr DoGet (const ObjectBase *object, uint32_t i) const { + const T *obj = static_cast (object); + typename U::const_iterator begin = (obj->*m_memberVector).begin (); + typename U::const_iterator end = (obj->*m_memberVector).end (); + uint32_t k = 0; + for (typename U::const_iterator j = begin; j != end; j++, k++) + { + if (k == i) + { + return *j; + break; + } + } + NS_ASSERT (false); + // quiet compiler. + return 0; + } + U T::*m_memberVector; + } *spec = new MemberStdContainer (); + spec->m_memberVector = memberVector; + return Ptr (spec, false); +} + +template +Ptr +MakeObjectVectorAccessor (Ptr (T::*get) (INDEX) const, + INDEX (T::*getN) (void) const) +{ + struct MemberGetters : public ObjectVectorAccessor + { + virtual bool DoGetN (const ObjectBase *object, uint32_t *n) const { + const T *obj = dynamic_cast (object); + if (obj == 0) + { + return false; + } + *n = (obj->*m_getN) (); + return true; + } + virtual Ptr DoGet (const ObjectBase *object, uint32_t i) const { + const T *obj = static_cast (object); + return (obj->*m_get) (i); + } + Ptr (T::*m_get) (INDEX) const; + INDEX (T::*m_getN) (void) const; + } *spec = new MemberGetters (); + spec->m_get = get; + spec->m_getN = getN; + return Ptr (spec, false); +} + +template +Ptr +MakeObjectVectorAccessor (INDEX (T::*getN) (void) const, + Ptr (T::*get) (INDEX) const) +{ + return MakeObjectVectorAccessor (get, getN); +} + +} // namespace ns3 + +#endif /* OBJECT_VECTOR_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/object.cc --- a/src/core/object.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/object.cc Wed Feb 27 22:19:39 2008 +0100 @@ -22,8 +22,12 @@ #include "assert.h" #include "singleton.h" #include "trace-resolver.h" +#include "attribute.h" +#include "trace-source-accessor.h" #include "log.h" +#include "string.h" #include +#include NS_LOG_COMPONENT_DEFINE ("Object"); @@ -36,25 +40,69 @@ class IidManager { public: + IidManager (); uint16_t AllocateUid (std::string name); void SetParent (uint16_t uid, uint16_t parent); + void SetTypeName (uint16_t uid, std::string typeName); + void SetGroupName (uint16_t uid, std::string groupName); void AddConstructor (uint16_t uid, ns3::CallbackBase callback, uint32_t nArguments); uint16_t GetUid (std::string name) const; std::string GetName (uint16_t uid) const; uint16_t GetParent (uint16_t uid) const; + std::string GetTypeName (uint16_t uid) const; + std::string GetGroupName (uint16_t uid) const; ns3::CallbackBase GetConstructor (uint16_t uid, uint32_t nArguments); bool HasConstructor (uint16_t uid); uint32_t GetRegisteredN (void); uint16_t GetRegistered (uint32_t i); + void AddAttribute (uint16_t uid, + std::string name, + std::string help, + uint32_t flags, + ns3::Attribute initialValue, + ns3::Ptr spec, + ns3::Ptr checker); + uint32_t GetAttributeListN (uint16_t uid) const; + std::string GetAttributeName (uint16_t uid, uint32_t i) const; + uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const; + ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const; + ns3::Ptr GetAttributeAccessor (uint16_t uid, uint32_t i) const; + ns3::Ptr GetAttributeChecker (uint16_t uid, uint32_t i) const; + void AddTraceSource (uint16_t uid, + std::string name, + std::string help, + ns3::Ptr accessor); + uint32_t GetTraceSourceN (uint16_t uid) const; + std::string GetTraceSourceName (uint16_t uid, uint32_t i) const; + std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const; + ns3::Ptr GetTraceSourceAccessor (uint16_t uid, uint32_t i) const; + private: struct ConstructorInformation { ns3::CallbackBase cb; uint32_t nArguments; }; + struct AttributeInformation { + std::string name; + std::string help; + uint32_t flags; + ns3::Attribute initialValue; + ns3::Ptr param; + ns3::Ptr checker; + }; + struct TraceSourceInformation { + std::string name; + std::string help; + ns3::Ptr accessor; + }; struct IidInformation { std::string name; uint16_t parent; + std::string typeName; + std::string groupName; std::vector constructors; + std::vector attributes; + std::vector traceSources; }; typedef std::vector::const_iterator Iterator; @@ -63,6 +111,9 @@ std::vector m_information; }; +IidManager::IidManager () +{} + uint16_t IidManager::AllocateUid (std::string name) { @@ -79,6 +130,8 @@ struct IidInformation information; information.name = name; information.parent = 0; + information.typeName = ""; + information.groupName = ""; m_information.push_back (information); uint32_t uid = m_information.size (); NS_ASSERT (uid <= 0xffff); @@ -100,6 +153,19 @@ information->parent = parent; } void +IidManager::SetTypeName (uint16_t uid, std::string typeName) +{ + struct IidInformation *information = LookupInformation (uid); + information->typeName = typeName; +} +void +IidManager::SetGroupName (uint16_t uid, std::string groupName) +{ + struct IidInformation *information = LookupInformation (uid); + information->groupName = groupName; +} + +void IidManager::AddConstructor (uint16_t uid, ns3::CallbackBase callback, uint32_t nArguments) { struct IidInformation *information = LookupInformation (uid); @@ -145,6 +211,19 @@ struct IidInformation *information = LookupInformation (uid); return information->parent; } +std::string +IidManager::GetTypeName (uint16_t uid) const +{ + struct IidInformation *information = LookupInformation (uid); + return information->typeName; +} +std::string +IidManager::GetGroupName (uint16_t uid) const +{ + struct IidInformation *information = LookupInformation (uid); + return information->groupName; +} + ns3::CallbackBase IidManager::GetConstructor (uint16_t uid, uint32_t nArguments) { @@ -179,6 +258,118 @@ return i + 1; } +void +IidManager::AddAttribute (uint16_t uid, + std::string name, + std::string help, + uint32_t flags, + ns3::Attribute initialValue, + ns3::Ptr spec, + ns3::Ptr checker) +{ + struct IidInformation *information = LookupInformation (uid); + for (std::vector::const_iterator j = information->attributes.begin (); + j != information->attributes.end (); j++) + { + if (j->name == name) + { + NS_FATAL_ERROR ("Registered the same attribute twice name=\""<name<<"\""); + return; + } + } + struct AttributeInformation param; + param.name = name; + param.help = help; + param.flags = flags; + param.initialValue = initialValue; + param.param = spec; + param.checker = checker; + information->attributes.push_back (param); +} + + +uint32_t +IidManager::GetAttributeListN (uint16_t uid) const +{ + struct IidInformation *information = LookupInformation (uid); + return information->attributes.size (); +} +std::string +IidManager::GetAttributeName (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->attributes.size ()); + return information->attributes[i].name; +} +uint32_t +IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->attributes.size ()); + return information->attributes[i].flags; +} +ns3::Attribute +IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->attributes.size ()); + return information->attributes[i].initialValue; +} +ns3::Ptr +IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->attributes.size ()); + return information->attributes[i].param; +} +ns3::Ptr +IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->attributes.size ()); + return information->attributes[i].checker; +} + +void +IidManager::AddTraceSource (uint16_t uid, + std::string name, + std::string help, + ns3::Ptr accessor) +{ + struct IidInformation *information = LookupInformation (uid); + struct TraceSourceInformation source; + source.name = name; + source.help = help; + source.accessor = accessor; + information->traceSources.push_back (source); +} +uint32_t +IidManager::GetTraceSourceN (uint16_t uid) const +{ + struct IidInformation *information = LookupInformation (uid); + return information->traceSources.size (); +} +std::string +IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->traceSources.size ()); + return information->traceSources[i].name; +} +std::string +IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->traceSources.size ()); + return information->traceSources[i].help; +} +ns3::Ptr +IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const +{ + struct IidInformation *information = LookupInformation (uid); + NS_ASSERT (i < information->traceSources.size ()); + return information->traceSources[i].accessor; +} } // anonymous namespace @@ -253,7 +444,11 @@ * The TypeId class *********************************************************************/ -TypeId::TypeId (std::string name) +TypeId::TypeId () + : m_tid (0) +{} + +TypeId::TypeId (const char * name) { uint16_t uid = Singleton::Get ()->AllocateUid (name); NS_ASSERT (uid != 0); @@ -273,6 +468,19 @@ NS_ASSERT (uid != 0); return TypeId (uid); } +bool +TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info) +{ + std::string::size_type pos = fullName.find ("::"); + if (pos == std::string::npos) + { + return 0; + } + std::string tidName = fullName.substr (0, pos); + std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2)); + TypeId tid = LookupByName (tidName); + return tid.LookupAttributeByName (paramName, info); +} uint32_t TypeId::GetRegisteredN (void) { @@ -284,6 +492,55 @@ return TypeId (Singleton::Get ()->GetRegistered (i)); } +bool +TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const +{ + TypeId tid; + TypeId nextTid = *this; + do { + tid = nextTid; + for (uint32_t i = 0; i < tid.GetAttributeListN (); i++) + { + std::string paramName = tid.GetAttributeName (i); + if (paramName == name) + { + info->accessor = tid.GetAttributeAccessor (i); + info->flags = tid.GetAttributeFlags (i); + info->initialValue = tid.GetAttributeInitialValue (i); + info->checker = tid.GetAttributeChecker (i); + return true; + } + } + nextTid = tid.GetParent (); + } while (nextTid != tid); + return false; +} +bool +TypeId::LookupAttributeByPosition (uint32_t i, struct TypeId::AttributeInfo *info) const +{ + uint32_t cur = 0; + TypeId tid; + TypeId nextTid = *this; + do { + tid = nextTid; + for (uint32_t j = 0; j < tid.GetAttributeListN (); j++) + { + if (cur == i) + { + info->accessor = tid.GetAttributeAccessor (j); + info->flags = tid.GetAttributeFlags (j); + info->initialValue = tid.GetAttributeInitialValue (j); + info->checker = tid.GetAttributeChecker (j); + return true; + } + cur++; + } + nextTid = tid.GetParent (); + } while (nextTid != tid); + return false; +} + + TypeId TypeId::SetParent (TypeId tid) { @@ -291,12 +548,37 @@ return *this; } TypeId +TypeId::SetGroupName (std::string groupName) +{ + Singleton::Get ()->SetGroupName (m_tid, groupName); + return *this; +} +TypeId +TypeId::SetTypeName (std::string typeName) +{ + Singleton::Get ()->SetTypeName (m_tid, typeName); + return *this; +} +TypeId TypeId::GetParent (void) const { uint16_t parent = Singleton::Get ()->GetParent (m_tid); return TypeId (parent); } std::string +TypeId::GetGroupName (void) const +{ + std::string groupName = Singleton::Get ()->GetGroupName (m_tid); + return groupName; +} +std::string +TypeId::GetTypeName (void) const +{ + std::string typeName = Singleton::Get ()->GetTypeName (m_tid); + return typeName; +} + +std::string TypeId::GetName (void) const { std::string name = Singleton::Get ()->GetName (m_tid); @@ -316,22 +598,163 @@ Singleton::Get ()->AddConstructor (m_tid, cb, nArguments); } +TypeId +TypeId::AddAttribute (std::string name, + std::string help, + Attribute initialValue, + Ptr param, + Ptr checker) +{ + Singleton::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker); + return *this; +} + +TypeId +TypeId::AddAttribute (std::string name, + std::string help, + uint32_t flags, + Attribute initialValue, + Ptr param, + Ptr checker) +{ + Singleton::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker); + return *this; +} + + CallbackBase -TypeId::LookupConstructor (uint32_t nArguments) +TypeId::LookupConstructor (uint32_t nArguments) const { CallbackBase constructor = Singleton::Get ()->GetConstructor (m_tid, nArguments); return constructor; } Ptr -TypeId::CreateObject (void) +TypeId::CreateObject (void) const +{ + return CreateObject (AttributeList ()); +} +Ptr +TypeId::CreateObject (const AttributeList &attributes) const { CallbackBase cb = LookupConstructor (0); - Callback > realCb; + Callback,const AttributeList &> realCb; realCb.Assign (cb); - Ptr object = realCb (); - return object; + Ptr object = realCb (attributes); + return object; +} + +uint32_t +TypeId::GetAttributeListN (void) const +{ + uint32_t n = Singleton::Get ()->GetAttributeListN (m_tid); + return n; +} +std::string +TypeId::GetAttributeName (uint32_t i) const +{ + std::string name = Singleton::Get ()->GetAttributeName (m_tid, i); + return name; +} +std::string +TypeId::GetAttributeFullName (uint32_t i) const +{ + return GetName () + "::" + GetAttributeName (i); +} +Attribute +TypeId::GetAttributeInitialValue (uint32_t i) const +{ + Attribute value = Singleton::Get ()->GetAttributeInitialValue (m_tid, i); + return value; +} +Ptr +TypeId::GetAttributeAccessor (uint32_t i) const +{ + // Used exclusively by the Object class. + Ptr param = Singleton::Get ()->GetAttributeAccessor (m_tid, i); + return param; +} +uint32_t +TypeId::GetAttributeFlags (uint32_t i) const +{ + // Used exclusively by the Object class. + uint32_t flags = Singleton::Get ()->GetAttributeFlags (m_tid, i); + return flags; +} +Ptr +TypeId::GetAttributeChecker (uint32_t i) const +{ + // Used exclusively by the Object class. + Ptr checker = Singleton::Get ()->GetAttributeChecker (m_tid, i); + return checker; +} + +uint32_t +TypeId::GetTraceSourceN (void) const +{ + return Singleton::Get ()->GetTraceSourceN (m_tid); } +std::string +TypeId::GetTraceSourceName (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceName (m_tid, i); +} +std::string +TypeId::GetTraceSourceHelp (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceHelp (m_tid, i); +} +Ptr +TypeId::GetTraceSourceAccessor (uint32_t i) const +{ + return Singleton::Get ()->GetTraceSourceAccessor (m_tid, i); +} + +TypeId +TypeId::AddTraceSource (std::string name, + std::string help, + Ptr accessor) +{ + Singleton::Get ()->AddTraceSource (m_tid, name, help, accessor); + return *this; +} + + +Ptr +TypeId::LookupTraceSourceByName (std::string name) const +{ + TypeId tid; + TypeId nextTid = *this; + do { + tid = nextTid; + for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++) + { + std::string srcName = tid.GetTraceSourceName (i); + if (srcName == name) + { + return tid.GetTraceSourceAccessor (i); + } + } + nextTid = tid.GetParent (); + } while (nextTid != tid); + return 0; +} + +std::ostream & operator << (std::ostream &os, TypeId tid) +{ + os << tid.GetName (); + return os; +} +std::istream & operator >> (std::istream &is, TypeId &tid) +{ + std::string tidString; + is >> tidString; + tid = TypeId::LookupByName (tidString); + return is; +} + + +VALUE_HELPER_CPP (TypeId); bool operator == (TypeId a, TypeId b) { @@ -344,6 +767,217 @@ } /********************************************************************* + * The AttributeList container implementation + *********************************************************************/ + +AttributeList::AttributeList () +{} + +AttributeList::AttributeList (const AttributeList &o) +{ + for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++) + { + struct Attr attr; + attr.checker = i->checker; + attr.value = i->value.Copy (); + m_attributes.push_back (attr); + } +} +AttributeList & +AttributeList::operator = (const AttributeList &o) +{ + Reset (); + for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++) + { + struct Attr attr; + attr.checker = i->checker; + attr.value = i->value.Copy (); + m_attributes.push_back (attr); + } + return *this; +} +AttributeList::~AttributeList () +{ + Reset (); +} + +bool +AttributeList::Set (std::string name, Attribute value) +{ + struct TypeId::AttributeInfo info; + TypeId::LookupAttributeByFullName (name, &info); + bool ok = DoSet (&info, value); + return ok; +} +void +AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value) +{ + struct TypeId::AttributeInfo info; + tid.LookupAttributeByName (name, &info); + DoSet (&info, value); +} +void +AttributeList::SetWithTid (TypeId tid, uint32_t position, Attribute value) +{ + struct TypeId::AttributeInfo info; + tid.LookupAttributeByPosition (position, &info); + DoSet (&info, value); +} + +void +AttributeList::DoSetOne (Ptr checker, Attribute value) +{ + // get rid of any previous value stored in this + // vector of values. + for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++) + { + if (k->checker == checker) + { + m_attributes.erase (k); + break; + } + } + // store the new value. + struct Attr attr; + attr.checker = checker; + attr.value = value.Copy (); + m_attributes.push_back (attr); +} +bool +AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value) +{ + if (info->checker == 0) + { + return false; + } + bool ok = info->checker->Check (value); + if (!ok) + { + // attempt to convert to string. + const StringValue *str = value.DynCast (); + if (str == 0) + { + return false; + } + // attempt to convert back to value. + Attribute v = info->initialValue.Copy (); + ok = v.DeserializeFromString (str->Get ().Get (), info->checker); + if (!ok) + { + return false; + } + ok = info->checker->Check (v); + if (!ok) + { + return false; + } + value = v; + } + DoSetOne (info->checker, value); + return true; +} +void +AttributeList::Reset (void) +{ + m_attributes.clear (); +} +AttributeList * +AttributeList::GetGlobal (void) +{ + return Singleton::Get (); +} + +std::string +AttributeList::LookupAttributeFullNameByChecker (Ptr checker) const +{ + for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++) + { + TypeId tid = TypeId::GetRegistered (i); + for (uint32_t j = 0; j < tid.GetAttributeListN (); j++) + { + if (checker == tid.GetAttributeChecker (j)) + { + return tid.GetAttributeFullName (j); + } + } + } + NS_FATAL_ERROR ("Could not find requested Accessor."); + // quiet compiler. + return ""; +} + +std::string +AttributeList::SerializeToString (void) const +{ + std::ostringstream oss; + for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++) + { + std::string name = LookupAttributeFullNameByChecker (i->checker); + oss << name << "=" << i->value.SerializeToString (i->checker); + if (i != m_attributes.end ()) + { + oss << "|"; + } + } + return oss.str (); +} +bool +AttributeList::DeserializeFromString (std::string str) +{ + Reset (); + + std::string::size_type cur; + cur = 0; + do { + std::string::size_type equal = str.find ("=", cur); + if (equal == std::string::npos) + { + // XXX: invalid attribute. + break; + } + else + { + std::string name = str.substr (cur, equal-cur); + struct TypeId::AttributeInfo info; + if (!TypeId::LookupAttributeByFullName (name, &info)) + { + // XXX invalid name. + break; + } + else + { + std::string::size_type next = str.find ("|", cur); + std::string value; + if (next == std::string::npos) + { + value = str.substr (equal+1, str.size () - (equal+1)); + cur = str.size (); + } + else + { + value = str.substr (equal+1, next - (equal+1)); + cur++; + } + Attribute val = info.initialValue.Copy (); + bool ok = val.DeserializeFromString (value, info.checker); + if (!ok) + { + // XXX invalid value + break; + } + else + { + DoSetOne (info.checker, val); + } + } + } + } while (cur != str.size ()); + + return true; +} + + +/********************************************************************* * The Object implementation *********************************************************************/ @@ -376,6 +1010,185 @@ { m_next = 0; } +void +Object::Construct (const AttributeList &attributes) +{ + // loop over the inheritance tree back to the Object base class. + TypeId tid = m_tid; + do { + // loop over all attributes in object type + NS_LOG_DEBUG ("construct tid="<checker == checker) + { + // We have a matching attribute value. + DoSet (paramSpec, initial, checker, j->value); + NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< + tid.GetAttributeName (i)<<"\""); + found = true; + break; + } + } + if (!found) + { + // is this attribute stored in the global instance instance ? + for (AttributeList::Attrs::const_iterator j = AttributeList::GetGlobal ()->m_attributes.begin (); + j != AttributeList::GetGlobal ()->m_attributes.end (); j++) + { + if (j->checker == checker) + { + // We have a matching attribute value. + DoSet (paramSpec, initial, checker, j->value); + NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< + tid.GetAttributeName (i)<<"\" from global"); + found = true; + break; + } + } + } + if (!found) + { + // No matching attribute value so we set the default value. + paramSpec->Set (this, initial); + NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<< + tid.GetAttributeName (i)<<"\" from local"); + } + } + tid = tid.GetParent (); + } while (tid != Object::GetTypeId ()); + NotifyConstructionCompleted (); +} +bool +Object::DoSet (Ptr spec, Attribute initialValue, + Ptr checker, Attribute value) +{ + bool ok = checker->Check (value); + if (!ok) + { + // attempt to convert to string + const StringValue *str = value.DynCast (); + if (str == 0) + { + return false; + } + // attempt to convert back from string. + Attribute v = initialValue.Copy (); + ok = v.DeserializeFromString (str->Get ().Get (), checker); + if (!ok) + { + return false; + } + ok = checker->Check (v); + if (!ok) + { + return false; + } + value = v; + } + ok = spec->Set (this, value); + return ok; +} +bool +Object::SetAttribute (std::string name, Attribute value) +{ + struct TypeId::AttributeInfo info; + if (!m_tid.LookupAttributeByName (name, &info)) + { + return false; + } + if (!(info.flags & TypeId::ATTR_SET)) + { + return false; + } + return DoSet (info.accessor, info.initialValue, info.checker, value); +} +bool +Object::GetAttribute (std::string name, std::string &value) const +{ + struct TypeId::AttributeInfo info; + if (!m_tid.LookupAttributeByName (name, &info)) + { + return false; + } + if (!(info.flags & TypeId::ATTR_GET)) + { + return false; + } + Attribute v = info.initialValue.Copy (); + bool ok = info.accessor->Get (this, v); + if (ok) + { + value = v.SerializeToString (info.checker); + } + return ok; +} + +Attribute +Object::GetAttribute (std::string name) const +{ + struct TypeId::AttributeInfo info; + if (!m_tid.LookupAttributeByName (name, &info)) + { + return Attribute (); + } + if (!(info.flags & TypeId::ATTR_GET)) + { + return Attribute (); + } + Attribute value = info.initialValue.Copy (); + bool ok = info.accessor->Get (this, value); + if (!ok) + { + return Attribute (); + } + return value; +} + +bool +Object::TraceSourceConnect (std::string name, const CallbackBase &cb) +{ + Ptr accessor = m_tid.LookupTraceSourceByName (name); + if (accessor == 0) + { + return false; + } + bool ok = accessor->Connect (this, cb); + return ok; +} +bool +Object::TraceSourceDisconnect (std::string name, const CallbackBase &cb) +{ + Ptr accessor = m_tid.LookupTraceSourceByName (name); + if (accessor == 0) + { + return false; + } + bool ok = accessor->Disconnect (this, cb); + return ok; +} + +TypeId +Object::GetRealTypeId (void) const +{ + return m_tid; +} + + Ptr Object::DoGetObject (TypeId tid) const { @@ -408,7 +1221,9 @@ current = current->m_next; } while (current != this); } - +void +Object::NotifyConstructionCompleted (void) +{} void Object::AggregateObject (Ptr o) { @@ -619,10 +1434,10 @@ static ns3::TypeId GetTypeId (void) { static ns3::TypeId tid = ns3::TypeId ("DerivedA") .SetParent (BaseA::GetTypeId ()) - .AddConstructor (); + .AddConstructor (); return tid; } - DerivedA (int v) + DerivedA () {} void DerivedGenerateTrace (int16_t v) { m_sourceDerived = v; } @@ -671,13 +1486,10 @@ static ns3::TypeId GetTypeId (void) { static ns3::TypeId tid = ns3::TypeId ("DerivedB") .SetParent (BaseB::GetTypeId ()) - .AddConstructor () - .AddConstructor (); + .AddConstructor (); return tid; } - DerivedB (int v) - {} - DerivedB (int v1, int &v2) + DerivedB () {} void DerivedGenerateTrace (int16_t v) { m_sourceDerived = v; } @@ -754,7 +1566,7 @@ NS_TEST_ASSERT_EQUAL (baseA->GetObject (), baseA); NS_TEST_ASSERT_EQUAL (baseA->GetObject (DerivedA::GetTypeId ()), 0); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), 0); - baseA = CreateObject (10); + baseA = CreateObject (); NS_TEST_ASSERT_EQUAL (baseA->GetObject (), baseA); NS_TEST_ASSERT_EQUAL (baseA->GetObject (DerivedA::GetTypeId ()), baseA); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); @@ -773,8 +1585,8 @@ NS_TEST_ASSERT_EQUAL (baseB->GetObject (), 0); NS_TEST_ASSERT_UNEQUAL (baseBCopy->GetObject (), 0); - baseA = CreateObject (1); - baseB = CreateObject (1); + baseA = CreateObject (); + baseB = CreateObject (); baseBCopy = baseB; baseA->AggregateObject (baseB); NS_TEST_ASSERT_UNEQUAL (baseA->GetObject (), 0); @@ -836,7 +1648,7 @@ baseA->TraceDisconnect ("/$BaseA/basea-x", MakeCallback (&ObjectTest::BaseATrace, this)); Ptr derivedA; - derivedA = CreateObject (1); + derivedA = CreateObject (); baseB = CreateObject (); derivedA->AggregateObject (baseB); baseB->TraceConnect ("/$DerivedA/deriveda-x", MakeCallback (&ObjectTest::DerivedATrace, this)); @@ -866,7 +1678,7 @@ NS_TEST_ASSERT_EQUAL (a->GetObject (), a); NS_TEST_ASSERT_EQUAL (a->GetObject (DerivedA::GetTypeId ()), 0); NS_TEST_ASSERT_EQUAL (a->GetObject (), 0); - a = DerivedA::GetTypeId ().CreateObject (10); + a = DerivedA::GetTypeId ().CreateObject (); NS_TEST_ASSERT_EQUAL (a->GetObject (), a); NS_TEST_ASSERT_EQUAL (a->GetObject (DerivedA::GetTypeId ()), a); NS_TEST_ASSERT_UNEQUAL (a->GetObject (), 0); diff -r d64b1561b1c2 -r e667dc0f350e src/core/object.h --- a/src/core/object.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/object.h Wed Feb 27 22:19:39 2008 +0100 @@ -26,13 +26,15 @@ #include "ptr.h" #include "trace-resolver.h" #include "callback.h" -#include "empty.h" +#include "attribute.h" +#include "object-base.h" +#include "attribute-helper.h" #define NS_OBJECT_ENSURE_REGISTERED(type) \ static struct X##type##RegistrationClass \ { \ X##type##RegistrationClass () { \ - ns3::TypeId tid = type::GetTypeId (); \ + ns3::TypeId tid = type::GetTypeId (); \ tid.GetParent (); \ } \ } x_##type##RegistrationVariable @@ -43,14 +45,30 @@ class TraceContext; class CallbackBase; class Object; +class AttributeAccessor; +class AttributeValue; +class AttributeList; +class TraceSourceAccessor; /** * \brief a unique identifier for an interface. * + * This class records a lot of meta-information about a + * subclass of the Object base class: + * - the base class of the subclass + * - the set of accessible constructors in the subclass + * - the set of 'attributes' accessible in the subclass */ class TypeId { public: + enum { + ATTR_GET = 1<<0, + ATTR_SET = 1<<1, + ATTR_CONSTRUCT = 1<<2, + ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT, + }; + /** * \param name the name of the requested interface * \returns the unique id associated with the requested @@ -60,8 +78,24 @@ * name is not a valid interface name. */ static TypeId LookupByName (std::string name); + + /** + * \returns the number of TypeId instances constructed + */ static uint32_t GetRegisteredN (void); + /** + * \param i index + * \returns the TypeId instance whose index is \i. + */ static TypeId GetRegistered (uint32_t i); + + /** + * \param name the name of the interface to construct. + * + * No two instances can share the same name. + */ + TypeId (const char * name); + /** * \returns the parent of this TypeId * @@ -74,6 +108,15 @@ TypeId GetParent (void) const; /** + * \returns the name of the group associated to this TypeId. + */ + std::string GetGroupName (void) const; + /** + * \returns the fully-qualified C++ typename of this TypeId. + */ + std::string GetTypeName (void) const; + + /** * \returns the name of this interface. */ std::string GetName (void) const; @@ -83,64 +126,280 @@ */ bool HasConstructor (void) const; - TypeId (std::string); + /** + * \returns the number of attributes associated to this TypeId + */ + uint32_t GetAttributeListN (void) const; + /** + * \param i index into attribute array + * \returns the name associated to the attribute whose + * index is \i i. + */ + std::string GetAttributeName (uint32_t i) const; + /** + * \param i index into attribute array + * \returns the full name associated to the attribute whose + * index is \i i. + */ + std::string GetAttributeFullName (uint32_t i) const; + + Attribute GetAttributeInitialValue (uint32_t i) const; + + uint32_t GetTraceSourceN (void) const; + std::string GetTraceSourceName (uint32_t i) const; + std::string GetTraceSourceHelp (uint32_t i) const; + Ptr GetTraceSourceAccessor (uint32_t i) const; + Ptr CreateObject (const AttributeList &attributes) const; + + + Ptr CreateObject (void) const; + template + Ptr CreateObject (T1 a1) const; + template + Ptr CreateObject (T1 a1, T2 a2) const; + + + /** + * \param tid the TypeId of the base class. + * \return this TypeId instance. + * + * Record in this TypeId which TypeId is the TypeId + * of the base class of the subclass. + */ TypeId SetParent (TypeId tid); + /** + * \return this TypeId instance. + * + * Record in this TypeId which TypeId is the TypeId + * of the base class of the subclass. + */ template TypeId SetParent (void); + /** + * \param groupName the name of the group this TypeId belongs to. + * \returns this TypeId instance. + * + * The group name is purely an advisory information used to + * group together types according to a user-specific grouping + * scheme. + */ + TypeId SetGroupName (std::string groupName); + + /** + * \param typeName the fully-qualified C++ typename of this TypeId. + * \returns this TypeId instance. + */ + TypeId SetTypeName (std::string typeName); + + /** + * \returns this TypeId instance + * + * Record in this TypeId the fact that the default constructor + * is accessible. + */ template TypeId AddConstructor (void); + template TypeId AddConstructor (void); + template TypeId AddConstructor (void); - template - TypeId AddConstructor (void); - template - TypeId AddConstructor (void); - template - TypeId AddConstructor (void); + + /** + * \param name the name of the new attribute + * \param help some help text which describes the purpose of this + * attribute + * \param param an instance of the associated Accessor subclass + * \returns this TypeId instance + * + * Record in this TypeId the fact that a new attribute exists. + */ + TypeId AddAttribute (std::string name, + std::string help, + Attribute initialValue, + Ptr spec, + Ptr checker); + + /** + * \param name the name of the new attribute + * \param help some help text which describes the purpose of this + * attribute + * \param flags flags which describe how this attribute can be read and/or written. + * \param param an instance of the associated Accessor subclass + * \returns this TypeId instance + * + * Record in this TypeId the fact that a new attribute exists. + */ + TypeId AddAttribute (std::string name, + std::string help, + uint32_t flags, + Attribute initialValue, + Ptr accessor, + Ptr checker); + + TypeId AddTraceSource (std::string name, + std::string help, + Ptr accessor); + + struct AttributeInfo { + Ptr accessor; + Attribute initialValue; + uint32_t flags; + Ptr checker; + }; + /** + * \param name the name of the requested attribute + */ + bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const; - Ptr CreateObject (void); - template - Ptr CreateObject (T1 a1); - template - Ptr CreateObject (T1 a1, T2 a2); - template - Ptr CreateObject (T1 a1, T2 a2, T3 a3); - template - Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4); - template - Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); + // construct an invalid TypeId. + TypeId (); + ~TypeId (); - ~TypeId (); + VALUE_HELPER_HEADER_1 (TypeId); private: + friend class Object; + friend class AttributeList; friend bool operator == (TypeId a, TypeId b); friend bool operator != (TypeId a, TypeId b); + + Ptr LookupTraceSourceByName (std::string name) const; + + /** + * \param i the position of the requested attribute + * \returns the Accessor associated to the requested attribute + */ + bool LookupAttributeByPosition (uint32_t i, struct AttributeInfo *info) const; + /** + * \param fullName the full name of the requested attribute + * \returns the Accessor associated to the requested attribute + */ + static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info); + explicit TypeId (uint16_t tid); void DoAddConstructor (CallbackBase callback, uint32_t nArguments); - CallbackBase LookupConstructor (uint32_t nArguments); + CallbackBase LookupConstructor (uint32_t nArguments) const; + Ptr GetAttributeAccessor (uint32_t i) const; + uint32_t GetAttributeFlags (uint32_t i) const; + Ptr GetAttributeChecker (uint32_t i) const; uint16_t m_tid; }; +std::ostream & operator << (std::ostream &os, TypeId tid); +std::istream & operator >> (std::istream &is, TypeId &tid); + +VALUE_HELPER_HEADER_2 (TypeId); + +/** + * \brief a container of attributes to be used during object's construction + * and in ns3::Object::Set. + * + */ +class AttributeList +{ +public: + AttributeList (); + AttributeList (const AttributeList &o); + AttributeList &operator = (const AttributeList &o); + ~AttributeList (); + /** + * \param name the name of the attribute to set + * \param value the value to set + * + * This method checks that a attribute with the requested + * name exists and that the value specified is an acceptable + * value of that attribute. If any of these checks fails, + * the program terminates with a message. + */ + bool Set (std::string name, Attribute value); + + void SetWithTid (TypeId tid, std::string name, Attribute value); + void SetWithTid (TypeId tid, uint32_t position, Attribute value); + + /** + * Clear the content of this instance. + */ + void Reset (void); + + /** + * \returns the global attribute container + * + * The global attribute container can be used to specify + * a set of attribute values without having to re-specify + * them for each object when it is created. This container + * is checked only during object construction and + * it is always checked last, after any per-object + * container is checked. + */ + static AttributeList *GetGlobal (void); + + std::string SerializeToString (void) const; + bool DeserializeFromString (std::string value); +private: + friend class Object; + struct Attr { + Ptr checker; + Attribute value; + }; + typedef std::vector Attrs; + typedef Attrs::iterator Iterator; + typedef Attrs::const_iterator CIterator; + + + + bool DoSet (struct TypeId::AttributeInfo *info, Attribute param); + void DoSetOne (Ptr checker, Attribute param); + std::string LookupAttributeFullNameByChecker (Ptr checker) const; + + Attrs m_attributes; +}; + + /** * \brief a base class which provides memory management and object aggregation * - * Note: This base class is quite similar in spirit to IUnknown in COM or - * BonoboObject in Bonobo: it provides three main methods: Ref, Unref and - * GetObject. */ -class Object +class Object : public ObjectBase { public: static TypeId GetTypeId (void); Object (); virtual ~Object (); + + /** + * \param name the name of the attribute to set + * \param value the name of the attribute to set + * + * Set a single attribute. + */ + bool SetAttribute (std::string name, Attribute value); + /** + * \param name the name of the attribute to read + * \param value a reference to the string where the value of the + * attribute should be stored. + * \returns true if the requested attribute was found, false otherwise. + */ + bool GetAttribute (std::string name, std::string &value) const; + /** + * \param name the name of the attribute to read + * \param value a reference to the object where the value of the + * attribute should be stored. + * \returns true if the requested attribute was found, false otherwise. + */ + Attribute GetAttribute (std::string name) const; + + bool TraceSourceConnect (std::string name, const CallbackBase &cb); + bool TraceSourceDisconnect (std::string name, const CallbackBase &cb); + + TypeId GetRealTypeId (void) const; + /** * Increment the reference count. This method should not be called * by user code. Object instances are expected to be used in conjunction @@ -214,8 +473,13 @@ * up to their parent's implementation once they are done. */ virtual void DoDispose (void); + virtual void NotifyConstructionCompleted (void); private: friend class TypeIdTraceResolver; + + template + friend Ptr CreateObject (const AttributeList &attributes); + template friend Ptr CreateObject (void); template @@ -233,57 +497,76 @@ template friend Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7); + + bool DoSet (Ptr spec, Attribute intialValue, + Ptr checker, Attribute value); Ptr DoGetObject (TypeId tid) const; void DoCollectSources (std::string path, const TraceContext &context, TraceResolver::SourceCollection *collection) const; void DoTraceAll (std::ostream &os, const TraceContext &context) const; bool Check (void) const; bool CheckLoose (void) const; + /** + * Attempt to delete this object. This method iterates + * over all aggregated objects to check if they all + * have a zero refcount. If yes, the object and all + * its aggregates are deleted. If not, nothing is done. + */ void MaybeDelete (void) const; /** * \param tid an TypeId * - * Every subclass which defines a new TypeId for itself - * should register this TypeId by calling this method - * from its constructor. + * Invoked from ns3::CreateObject only. + * Initialize the m_tid member variable to + * keep track of the type of this object instance. */ void SetTypeId (TypeId tid); + /** + * \param attributes the attribute values used to initialize + * the member variables of this object's instance. + * + * Invoked from ns3::CreateObject only. + * Initialize all the member variables which were + * registered with the associated TypeId. + */ + void Construct (const AttributeList &attributes); + /** + * The reference count for this object. Each aggregate + * has an individual reference count. When the global + * reference count (the sum of all reference counts) + * reaches zero, the object and all its aggregates is + * deleted. + */ mutable uint32_t m_count; + /** + * Identifies the type of this object instance. + */ TypeId m_tid; + /** + * Set to true when the DoDispose method of the object + * has run, false otherwise. + */ bool m_disposed; mutable bool m_collecting; + /** + * A pointer to the next aggregate object. This is a circular + * linked list of aggregated objects: the last one points + * back to the first one. If an object is not aggregated to + * any other object, the value of this field is equal to the + * value of the 'this' pointer. + */ Object *m_next; }; -template -Ptr CreateObject (void); - -template -Ptr CreateObject (T1 a1); - -template -Ptr CreateObject (T1 a1, T2 a2); - -template -Ptr CreateObject (T1 a1, T2 a2, T3 a3); - -template -Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4); - -template -Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5); - -template -Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6); - -template -Ptr CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7); - } // namespace ns3 namespace ns3 { +/************************************************************************* + * The TypeId implementation which depends on templates + *************************************************************************/ + template TypeId TypeId::SetParent (void) @@ -296,8 +579,8 @@ TypeId::AddConstructor (void) { struct Maker { - static Ptr Create (void) { - return ns3::CreateObject (); + static Ptr Create (const AttributeList &attributes) { + return ns3::CreateObject (attributes); } }; CallbackBase cb = MakeCallback (&Maker::Create); @@ -330,49 +613,9 @@ DoAddConstructor (cb, 2); return *this; } -template -TypeId -TypeId::AddConstructor (void) -{ - struct Maker { - static Ptr Create (T1 a1, T2 a2, T3 a3) { - return ns3::CreateObject (a1, a2, a3); - } - }; - CallbackBase cb = MakeCallback (&Maker::Create); - DoAddConstructor (cb, 3); - return *this; -} -template -TypeId -TypeId::AddConstructor (void) -{ - struct Maker { - static Ptr Create (T1 a1, T2 a2, T3 a3, T4 a4) { - return ns3::CreateObject (a1, a2, a3, a4); - } - }; - CallbackBase cb = MakeCallback (&Maker::Create); - DoAddConstructor (cb, 4); - return *this; -} -template -TypeId -TypeId::AddConstructor (void) -{ - struct Maker { - static Ptr Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) { - return ns3::CreateObject (a1, a2, a3, a4, a5); - } - }; - CallbackBase cb = MakeCallback (&Maker::Create); - DoAddConstructor (cb, 5); - return *this; -} - template Ptr -TypeId::CreateObject (T1 a1) +TypeId::CreateObject (T1 a1) const { CallbackBase cb = LookupConstructor (1); Callback,T1> realCb; @@ -382,7 +625,7 @@ } template Ptr -TypeId::CreateObject (T1 a1, T2 a2) +TypeId::CreateObject (T1 a1, T2 a2) const { CallbackBase cb = LookupConstructor (2); Callback,T1,T2> realCb; @@ -390,38 +633,10 @@ Ptr object = realCb (a1,a2); return object; } -template -Ptr -TypeId::CreateObject (T1 a1, T2 a2, T3 a3) -{ - CallbackBase cb = LookupConstructor (3); - Callback,T1,T2,T3> realCb; - realCb.Assign (cb); - Ptr object = realCb (a1,a2,a3); - return object; -} -template -Ptr -TypeId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4) -{ - CallbackBase cb = LookupConstructor (4); - Callback,T1,T2,T3,T4> realCb; - realCb.Assign (cb); - Ptr object = realCb (a1,a2,a3,a4); - return object; -} - template -Ptr -TypeId::CreateObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) -{ - CallbackBase cb = LookupConstructor (5); - Callback,T1,T2,T3,T4,T5> realCb; - realCb.Assign (cb); - Ptr object = realCb (a1,a2,a3,a4,a5); - return object; -} - +/************************************************************************* + * The Object implementation which depends on templates + *************************************************************************/ void Object::Ref (void) const @@ -463,11 +678,26 @@ return 0; } +/************************************************************************* + * The helper functions which need templates. + *************************************************************************/ + + +template +Ptr CreateObject (const AttributeList &attributes) +{ + Ptr p = Ptr (new T (), false); + p->SetTypeId (T::GetTypeId ()); + p->Object::Construct (attributes); + return p; +} + template Ptr CreateObject (void) { Ptr p = Ptr (new T (), false); p->SetTypeId (T::GetTypeId ()); + p->Object::Construct (AttributeList ()); return p; } @@ -476,6 +706,7 @@ { Ptr p = Ptr (new T (a1), false); p->SetTypeId (T::GetTypeId ()); + p->Object::Construct (AttributeList ()); return p; } @@ -484,9 +715,9 @@ { Ptr p = Ptr (new T (a1, a2), false); p->SetTypeId (T::GetTypeId ()); + p->Object::Construct (AttributeList ()); return p; } - template Ptr CreateObject (T1 a1, T2 a2, T3 a3) { @@ -528,6 +759,32 @@ } +template +Ptr +CreateObjectWith (std::string n1 = "", Attribute v1 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute (), + std::string n5 = "", Attribute v5 = Attribute (), + std::string n6 = "", Attribute v6 = Attribute (), + std::string n7 = "", Attribute v7 = Attribute (), + std::string n8 = "", Attribute v8 = Attribute (), + std::string n9 = "", Attribute v9 = Attribute ()) + +{ + AttributeList attributes; + attributes.SetWithTid (T::GetTypeId (), n1, v1); + attributes.SetWithTid (T::GetTypeId (), n2, v2); + attributes.SetWithTid (T::GetTypeId (), n3, v3); + attributes.SetWithTid (T::GetTypeId (), n4, v4); + attributes.SetWithTid (T::GetTypeId (), n5, v5); + attributes.SetWithTid (T::GetTypeId (), n6, v6); + attributes.SetWithTid (T::GetTypeId (), n7, v7); + attributes.SetWithTid (T::GetTypeId (), n8, v8); + attributes.SetWithTid (T::GetTypeId (), n9, v9); + return CreateObject (attributes); +} + } // namespace ns3 #endif /* OBJECT_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/ptr.cc --- a/src/core/ptr.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/ptr.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,6 +23,7 @@ #ifdef RUN_SELF_TESTS #include "test.h" +#include "object-base.h" namespace ns3 { @@ -45,7 +46,7 @@ }; -class Base +class Base : public ObjectBase { public: Base (); @@ -286,7 +287,6 @@ delete raw; } - m_nDestroyed = 0; { Ptr p = Create (this); @@ -317,12 +317,12 @@ } #if 0 { - Ptr p = CreateObject (cb); + Ptr p = Create (cb); Callback callback = MakeCallback (&NoCount::Nothing, p); callback (); } { - Ptr p = CreateObject (cb); + Ptr p = Create (cb); Callback callback = MakeCallback (&NoCount::Nothing, p); callback (); } diff -r d64b1561b1c2 -r e667dc0f350e src/core/random-variable.cc --- a/src/core/random-variable.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/random-variable.cc Wed Feb 27 22:19:39 2008 +0100 @@ -28,6 +28,7 @@ #include #include #include +#include #include "assert.h" @@ -51,7 +52,7 @@ RandomVariableBase (const RandomVariableBase &o); virtual ~RandomVariableBase(); virtual double GetValue() = 0; - virtual uint32_t GetIntValue(); + virtual uint32_t GetInteger(); virtual RandomVariableBase* Copy(void) const = 0; virtual void GetSeed(uint32_t seed[6]); @@ -126,7 +127,7 @@ delete m_generator; } -uint32_t RandomVariableBase::GetIntValue() +uint32_t RandomVariableBase::GetInteger() { return (uint32_t)GetValue(); } @@ -249,6 +250,10 @@ RandomVariable & RandomVariable::operator = (const RandomVariable &o) { + if (&o == this) + { + return *this; + } delete m_variable; m_variable = o.m_variable->Copy (); return *this; @@ -264,9 +269,9 @@ } uint32_t -RandomVariable::GetIntValue (void) const +RandomVariable::GetInteger (void) const { - return m_variable->GetIntValue (); + return m_variable->GetInteger (); } void RandomVariable::GetSeed(uint32_t seed[6]) const @@ -290,11 +295,27 @@ RandomVariableBase::SetRunNumber (n); } RandomVariableBase * -RandomVariable::Peek (void) +RandomVariable::Peek (void) const { return m_variable; } +RandomVariable::RandomVariable (Attribute value) + : m_variable (0) +{ + const RandomVariableValue *v = value.DynCast (); + if (v == 0) + { + NS_FATAL_ERROR ("Unexpected type of value. Expected \"RandomVariableValue\""); + } + *this = v->Get (); +} +RandomVariable::operator Attribute () const +{ + return Attribute::Create (*this); +} +ATTRIBUTE_VALUE_IMPLEMENT (RandomVariable); +ATTRIBUTE_CHECKER_IMPLEMENT (RandomVariable); //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -316,6 +337,9 @@ UniformVariableImpl(double s, double l); UniformVariableImpl(const UniformVariableImpl& c); + + double GetMin (void) const; + double GetMax (void) const; /** * \return A value between low and high values specified by the constructor @@ -344,6 +368,18 @@ UniformVariableImpl::UniformVariableImpl(const UniformVariableImpl& c) : RandomVariableBase(c), m_min(c.m_min), m_max(c.m_max) { } +double +UniformVariableImpl::GetMin (void) const +{ + return m_min; +} +double +UniformVariableImpl::GetMax (void) const +{ + return m_max; +} + + double UniformVariableImpl::GetValue() { if(!RandomVariableBase::initialized) @@ -420,7 +456,7 @@ * \return The constant value specified */ virtual double GetValue(); - virtual uint32_t GetIntValue(); + virtual uint32_t GetInteger(); virtual RandomVariableBase* Copy(void) const; private: double m_const; @@ -443,7 +479,7 @@ return m_const; } -uint32_t ConstantVariableImpl::GetIntValue() +uint32_t ConstantVariableImpl::GetInteger() { return (uint32_t)m_const; } @@ -1241,7 +1277,7 @@ /** * \return An integer value from this empirical distribution */ - virtual uint32_t GetIntValue(); + virtual uint32_t GetInteger(); private: virtual double Interpolate(double, double, double, double, double); }; @@ -1249,7 +1285,7 @@ IntEmpiricalVariableImpl::IntEmpiricalVariableImpl() { } -uint32_t IntEmpiricalVariableImpl::GetIntValue() +uint32_t IntEmpiricalVariableImpl::GetInteger() { return (uint32_t)GetValue(); } @@ -1563,6 +1599,55 @@ } +std::ostream &operator << (std::ostream &os, const RandomVariable &var) +{ + RandomVariableBase *base = var.Peek (); + ConstantVariableImpl *constant = dynamic_cast (base); + if (constant != 0) + { + os << "Constant:" << constant->GetValue (); + return os; + } + UniformVariableImpl *uniform = dynamic_cast (base); + if (uniform != 0) + { + os << "Uniform:" << uniform->GetMin () << ":" << uniform->GetMax (); + return os; + } + // XXX: support other distributions + os.setstate (std::ios_base::badbit); + return os; +} +std::istream &operator >> (std::istream &is, RandomVariable &var) +{ + std::string value; + is >> value; + std::string::size_type tmp; + tmp = value.find (":"); + if (tmp == std::string::npos) + { + is.setstate (std::ios_base::badbit); + return is; + } + std::string type = value.substr (0, tmp); + if (value == "Constant") + { + // XXX parse + var = ConstantVariable (); + } + else if (value == "Uniform") + { + // XXX parse + var = UniformVariable (); + } + else + { + // XXX: support other distributions. + } + return is; +} + + }//namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/random-variable.h --- a/src/core/random-variable.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/random-variable.h Wed Feb 27 22:19:39 2008 +0100 @@ -24,6 +24,10 @@ #include #include #include +#include +#include +#include "attribute.h" +#include "attribute-helper.h" /** * \ingroup core @@ -68,7 +72,7 @@ * \brief Returns a random integer integer from the underlying distribution * \return Integer cast of ::GetValue() */ - uint32_t GetIntValue (void) const; + uint32_t GetInteger (void) const; /** * \brief Get the internal state of the RNG @@ -158,11 +162,19 @@ * \endcode */ static void SetRunNumber(uint32_t n); + + + RandomVariable (Attribute value); + operator Attribute () const; + private: + friend std::ostream &operator << (std::ostream &os, const RandomVariable &var); + friend std::istream &operator >> (std::istream &os, RandomVariable &var); + RandomVariableBase *m_variable; protected: RandomVariable (const RandomVariableBase &variable); - RandomVariableBase *Peek (void); + RandomVariableBase *Peek (void) const; }; /** @@ -648,5 +660,14 @@ static double GetSingleValue(double s, double l, double mean); }; +std::ostream &operator << (std::ostream &os, const RandomVariable &var); +std::istream &operator >> (std::istream &os, RandomVariable &var); + +ATTRIBUTE_VALUE_DEFINE (RandomVariable); +ATTRIBUTE_CHECKER_DEFINE (RandomVariable); +ATTRIBUTE_ACCESSOR_DEFINE (RandomVariable); + }//namespace ns3 + + #endif diff -r d64b1561b1c2 -r e667dc0f350e src/core/string.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/string.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,45 @@ +#include "string.h" + +namespace ns3 { + +String::String () + : m_value () +{} +String::String (const char *value) + : m_value (value) +{} +String::String (std::string value) + : m_value (value) +{} +void +String::Set (std::string value) +{ + m_value = value; +} +void +String::Set (const char *value) +{ + m_value = value; +} +std::string +String::Get (void) const +{ + return m_value; +} + +std::ostream & operator << (std::ostream &os, const String &value) +{ + os << value.Get (); + return os; +} +std::istream &operator >> (std::istream &is, String &value) +{ + std::string str; + is >> str; + value = String (str); + return is; +} + +VALUE_HELPER_CPP (String); + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/string.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,32 @@ +#ifndef NS3_STRING_H +#define NS3_STRING_H + +#include +#include "attribute-helper.h" + +namespace ns3 { + +class String +{ +public: + String (); + String (const char *value); + String (std::string value); + void Set (std::string value); + void Set (const char *value); + std::string Get (void) const; + + VALUE_HELPER_HEADER_1 (String); +private: + std::string m_value; +}; + +std::ostream & operator << (std::ostream &os, const String &value); +std::istream &operator >> (std::istream &is, String &value); + +VALUE_HELPER_HEADER_2 (String); + +} // namespace ns3 + + +#endif /* NS3_STRING_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/trace-resolver.h --- a/src/core/trace-resolver.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/trace-resolver.h Wed Feb 27 22:19:39 2008 +0100 @@ -25,6 +25,7 @@ #include #include "trace-context.h" #include "trace-doc.h" +#include "object-base.h" namespace ns3 { @@ -39,7 +40,7 @@ * subclasses, doing so is complicated so, it is recommended to use * the default implementation ns3::CompositeTraceResolver instead. */ -class TraceResolver +class TraceResolver : public ObjectBase { public: diff -r d64b1561b1c2 -r e667dc0f350e src/core/trace-source-accessor.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/trace-source-accessor.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,25 @@ +#include "trace-source-accessor.h" + +namespace ns3 { + +TraceSourceAccessor::TraceSourceAccessor () + : m_count (1) +{} +TraceSourceAccessor::~TraceSourceAccessor () +{} +void +TraceSourceAccessor::Ref (void) const +{ + m_count++; +} +void +TraceSourceAccessor::Unref (void) const +{ + m_count--; + if (m_count == 0) + { + delete this; + } +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/trace-source-accessor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/trace-source-accessor.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,71 @@ +#ifndef TRACE_SOURCE_ACCESSOR_H +#define TRACE_SOURCE_ACCESSOR_H + +#include +#include "object-base.h" +#include "callback.h" +#include "ptr.h" + +namespace ns3 { + +class TraceSourceAccessor : public ObjectBase +{ +public: + TraceSourceAccessor (); + virtual ~TraceSourceAccessor (); + void Ref (void) const; + void Unref (void) const; + + virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const = 0; + virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const = 0; +private: + mutable uint32_t m_count; +}; + +template +Ptr MakeTraceSourceAccessor (T a); + +} // namespace ns3 + +namespace ns3 { + +template +Ptr +DoMakeTraceSourceAccessor (SOURCE T::*a) +{ + struct Accessor : public TraceSourceAccessor + { + virtual bool Connect (ObjectBase *obj, const CallbackBase &cb) const { + T *p = dynamic_cast (obj); + if (p == 0) + { + return false; + } + (p->*m_source).Connect (cb); + return true; + } + virtual bool Disconnect (ObjectBase *obj, const CallbackBase &cb) const { + T *p = dynamic_cast (obj); + if (p == 0) + { + return false; + } + (p->*m_source).Disconnect (cb); + return true; + } + SOURCE T::*m_source; + } *accessor = new Accessor (); + accessor->m_source = a; + return Ptr (accessor, false); +} + +template +Ptr MakeTraceSourceAccessor (T a) +{ + return DoMakeTraceSourceAccessor (a); +} + +} // namespace ns3 + + +#endif /* TRACE_SOURCE_ACCESSOR_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/traced-callback.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/traced-callback.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,100 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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: Mathieu Lacage + */ +#include "traced-callback.h" + +#ifdef RUN_SELF_TESTS + +#include "test.h" + +namespace ns3 { + +class TracedCallbackTest : public Test +{ +public: + TracedCallbackTest (); + virtual ~TracedCallbackTest (); + virtual bool RunTests (void); +private: + void CbOne (uint8_t a, double b); + void CbTwo (uint8_t a, double b); + + bool m_one; + bool m_two; +}; + +TracedCallbackTest::TracedCallbackTest () + : Test ("TracedCallback") +{} +TracedCallbackTest::~TracedCallbackTest () +{} +void +TracedCallbackTest::CbOne (uint8_t a, double b) +{ + m_one = true; +} +void +TracedCallbackTest::CbTwo (uint8_t a, double b) +{ + m_two = true; +} +bool +TracedCallbackTest::RunTests (void) +{ + bool result = true; + + TracedCallback trace; + trace.Connect (MakeCallback (&TracedCallbackTest::CbOne, this)); + trace.Connect (MakeCallback (&TracedCallbackTest::CbTwo, this)); + m_one = false; + m_two = false; + trace (1, 2); + NS_TEST_ASSERT (m_one); + NS_TEST_ASSERT (m_two); + + trace.Disconnect (MakeCallback (&TracedCallbackTest::CbOne, this)); + m_one = false; + m_two = false; + trace (1, 2); + NS_TEST_ASSERT (!m_one); + NS_TEST_ASSERT (m_two); + trace.Disconnect (MakeCallback (&TracedCallbackTest::CbTwo, this)); + m_one = false; + m_two = false; + trace (1, 2); + NS_TEST_ASSERT (!m_one); + NS_TEST_ASSERT (!m_two); + + trace.Connect (MakeCallback (&TracedCallbackTest::CbOne, this)); + trace.Connect (MakeCallback (&TracedCallbackTest::CbTwo, this)); + m_one = false; + m_two = false; + trace (1, 2); + NS_TEST_ASSERT (m_one); + NS_TEST_ASSERT (m_two); + + return result; +} + +static TracedCallbackTest g_eventTraceTest; + +}//namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/traced-callback.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/traced-callback.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,153 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005,2006,2007 INRIA + * All rights reserved. + * + * 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: Mathieu Lacage + */ + +#ifndef TRACED_CALLBACK_H +#define TRACED_CALLBACK_H + +#include +#include "callback.h" + +namespace ns3 { + +/** + * \brief log arbitrary number of parameters to a matching ns3::Callback + * \ingroup tracing + * + * Whenever operator () is invoked on this class, the call and its arguments + * are forwarded to the internal matching ns3::Callback. + */ +template +class TracedCallback +{ +public: + TracedCallback (); + void Connect (const CallbackBase & callback); + void Disconnect (const CallbackBase & callback); + void operator() (void) const; + void operator() (T1 a1) const; + void operator() (T1 a1, T2 a2) const; + void operator() (T1 a1, T2 a2, T3 a3) const; + void operator() (T1 a1, T2 a2, T3 a3, T4 a4) const; + +private: + typedef std::list > CallbackList; + CallbackList m_callbackList; +}; + +} // namespace ns3 + +// implementation below. + +namespace ns3 { + + +template +TracedCallback::TracedCallback () + : m_callbackList () +{} +template +void +TracedCallback::Connect (const CallbackBase & callback) +{ + Callback cb; + cb.Assign (callback); + m_callbackList.push_back (cb); +} +template +void +TracedCallback::Disconnect (const CallbackBase & callback) +{ + for (typename CallbackList::iterator i = m_callbackList.begin (); + i != m_callbackList.end (); /* empty */) + { + if ((*i).IsEqual (callback)) + { + i = m_callbackList.erase (i); + } + else + { + i++; + } + } +} +template +void +TracedCallback::operator() (void) const +{ + for (typename CallbackList::const_iterator i = m_callbackList.begin (); + i != m_callbackList.end (); i++) + { + (*i) (); + } +} +template +void +TracedCallback::operator() (T1 a1) const +{ + for (typename CallbackList::const_iterator i = m_callbackList.begin (); + i != m_callbackList.end (); i++) + { + (*i) (a1); + } +} +template +void +TracedCallback::operator() (T1 a1, T2 a2) const +{ + for (typename CallbackList::const_iterator i = m_callbackList.begin (); + i != m_callbackList.end (); i++) + { + (*i) (a1, a2); + } +} +template +void +TracedCallback::operator() (T1 a1, T2 a2, T3 a3) const +{ + for (typename CallbackList::const_iterator i = m_callbackList.begin (); + i != m_callbackList.end (); i++) + { + (*i) (a1, a2, a3); + } +} +template +void +TracedCallback::operator() (T1 a1, T2 a2, T3 a3, T4 a4) const +{ + for (typename CallbackList::const_iterator i = m_callbackList.begin (); + i != m_callbackList.end (); i++) + { + (*i) (a1, a2, a3, a4); + } +} + +}//namespace ns3 + +#endif /* TRACED_CALLBACK_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/traced-value.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/traced-value.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,480 @@ +#ifndef TRACED_VALUE_H +#define TRACED_VALUE_H + +#include "traced-callback.h" +#include "integer.h" +#include "uinteger.h" +#include "boolean.h" +#include "double.h" +#include "enum.h" + +#define TRACE(x) + +namespace ns3 { + +template +class TracedValue +{ +public: + TracedValue () + : m_v () {} + TracedValue (const TracedValue &o) + : m_v (o.m_v) {} + TracedValue (const T &v) + : m_v (v) {} + operator T () const { + return m_v; + } + TracedValue &operator = (const TracedValue &o) { + TRACE ("x="); + Set (o.m_v); + return *this; + } + TracedValue (const Integer &value) + : m_v (value.Get ()) {} + operator Integer () const { + return Integer (m_v); + } + TracedValue (const Uinteger &value) + : m_v (value.Get ()) {} + operator Uinteger () const { + return Uinteger (m_v); + } + TracedValue (const Boolean &value) + : m_v (value.Get ()) {} + operator Boolean () const { + return Boolean (m_v); + } + TracedValue (const Enum &value) + : m_v (value.Get ()) {} + operator Enum () const { + return Enum (m_v); + } + void Connect (const CallbackBase &cb) { + m_cb.Connect (cb); + } + void Disconnect (const CallbackBase &cb) { + m_cb.Disconnect (cb); + } + void Set (const T &v) { + if (m_v != v) + { + m_cb (m_v, v); + m_v = v; + } + } + T Get (void) const { + return m_v; + } + TracedValue &operator++ () { + TRACE ("++x"); + T tmp = Get (); + ++tmp; + Set (tmp); + return *this; + } + TracedValue &operator-- () { + TRACE ("--x"); + T tmp = Get (); + --tmp; + Set (tmp); + return *this; + } + TracedValue operator++ (int) { + TRACE ("x++"); + TracedValue old (*this); + T tmp = Get (); + tmp++; + Set (tmp); + return old; + } + TracedValue operator-- (int) { + TRACE ("x--"); + TracedValue old (*this); + T tmp = Get (); + tmp--; + Set (tmp); + return old; + } +private: + T m_v; + TracedCallback m_cb; +}; + +template +bool operator == (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x==x"); + return lhs.Get () == rhs.Get (); +} +template +bool operator == (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x=="); + return lhs.Get () == rhs; +} +template +bool operator == (const U &lhs, const TracedValue &rhs) +{ + TRACE ("==x"); + return lhs == rhs.Get (); +} + +template +bool operator != (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x!=x"); + return lhs.Get () != rhs.Get (); +} +template +bool operator != (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x!="); + return lhs.Get () != rhs; +} +template +bool operator != (const U &lhs, const TracedValue &rhs) +{ + TRACE ("!=x"); + return lhs != rhs.Get (); +} + +template +bool operator <= (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x<=x"); + return lhs.Get () <= rhs.Get (); +} +template +bool operator <= (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x<="); + return lhs.Get () <= rhs; +} +template +bool operator <= (const U &lhs, const TracedValue &rhs) +{ + TRACE ("<=x"); + return lhs <= rhs.Get (); +} +template +bool operator >= (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x>=x"); + return lhs.Get () >= rhs.Get (); +} +template +bool operator >= (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x>="); + return lhs.Get () >= rhs; +} +template +bool operator >= (const U &lhs, const TracedValue &rhs) +{ + TRACE (">=x"); + return lhs >= rhs.Get (); +} + +template +bool operator < (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x +bool operator < (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x<"); + return lhs.Get () < rhs; +} +template +bool operator < (const U &lhs, const TracedValue &rhs) +{ + TRACE (" +bool operator > (const TracedValue &lhs, const TracedValue &rhs) +{ + TRACE ("x>x"); + return lhs.Get () > rhs.Get (); +} +template +bool operator > (const TracedValue &lhs, const U &rhs) +{ + TRACE ("x>"); + return lhs.Get () > rhs; +} +template +bool operator > (const U &lhs, const TracedValue &rhs) +{ + TRACE (">x"); + return lhs > rhs.Get (); +} +template +TracedValue &operator += (TracedValue &lhs, const U &rhs) { + TRACE ("x+="); + T tmp = lhs.Get (); + tmp += rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator -= (TracedValue &lhs, const U &rhs) { + TRACE ("x-="); + T tmp = lhs.Get (); + tmp -= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator *= (TracedValue &lhs, const U &rhs) { + TRACE ("x*="); + T tmp = lhs.Get (); + tmp *= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator /= (TracedValue &lhs, const U &rhs) { + TRACE ("x/="); + T tmp = lhs.Get (); + tmp /= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator %= (TracedValue &lhs, const U &rhs) { + TRACE ("x%="); + T tmp = lhs.Get (); + tmp %= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator <<= (TracedValue &lhs, const U &rhs) { + TRACE ("x<<="); + T tmp = lhs.Get (); + tmp <<= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator >>= (TracedValue &lhs, const U &rhs) { + TRACE ("x>>="); + T tmp = lhs.Get (); + tmp >>= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator &= (TracedValue &lhs, const U &rhs) { + TRACE ("x&="); + T tmp = lhs.Get (); + tmp &= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator |= (TracedValue &lhs, const U &rhs) { + TRACE ("x|="); + T tmp = lhs.Get (); + tmp |= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue &operator ^= (TracedValue &lhs, const U &rhs) { + TRACE ("x^="); + T tmp = lhs.Get (); + tmp ^= rhs; + lhs.Set (tmp); + return lhs; +} +template +TracedValue operator + (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x+x"); + return TracedValue (lhs.Get () + rhs.Get ()); +} +template +TracedValue operator + (const TracedValue &lhs, const U &rhs) { + TRACE ("x+"); + return TracedValue (lhs.Get () + rhs); +} +template +TracedValue operator + (const U &lhs, const TracedValue &rhs) { + TRACE ("+x"); + return TracedValue (lhs + rhs.Get ()); +} + +template +TracedValue operator - (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x-x"); + return TracedValue (lhs.Get () - rhs.Get ()); +} +template +TracedValue operator - (const TracedValue &lhs, const U &rhs) { + TRACE ("x-"); + return TracedValue (lhs.Get () - rhs); +} +template +TracedValue operator - (const U &lhs, const TracedValue &rhs) { + TRACE ("-x"); + return TracedValue (lhs - rhs.Get ()); +} + +template +TracedValue operator * (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x*x"); + return TracedValue (lhs.Get () * rhs.Get ()); +} +template +TracedValue operator * (const TracedValue &lhs, const U &rhs) { + TRACE ("x*"); + return TracedValue (lhs.Get () * rhs); +} +template +TracedValue operator * (const U &lhs, const TracedValue &rhs) { + TRACE ("*x"); + return TracedValue (lhs - rhs.Get ()); +} + +template +TracedValue operator / (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x/x"); + return TracedValue (lhs.Get () / rhs.Get ()); +} +template +TracedValue operator / (const TracedValue &lhs, const U &rhs) { + TRACE ("x/"); + return TracedValue (lhs.Get () / rhs); +} +template +TracedValue operator / (const U &lhs, const TracedValue &rhs) { + TRACE ("/x"); + return TracedValue (lhs / rhs.Get ()); +} + +template +TracedValue operator % (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x%x"); + return TracedValue (lhs.Get () % rhs.Get ()); +} +template +TracedValue operator % (const TracedValue &lhs, const U &rhs) { + TRACE ("x%"); + return TracedValue (lhs.Get () % rhs); +} +template +TracedValue operator % (const U &lhs, const TracedValue &rhs) { + TRACE ("%x"); + return TracedValue (lhs % rhs.Get ()); +} + +template +TracedValue operator ^ (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x^x"); + return TracedValue (lhs.Get () ^ rhs.Get ()); +} +template +TracedValue operator ^ (const TracedValue &lhs, const U &rhs) { + TRACE ("x^"); + return TracedValue (lhs.Get () ^ rhs); +} +template +TracedValue operator ^ (const U &lhs, const TracedValue &rhs) { + TRACE ("^x"); + return TracedValue (lhs ^ rhs.Get ()); +} + +template +TracedValue operator | (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x|x"); + return TracedValue (lhs.Get () | rhs.Get ()); +} +template +TracedValue operator | (const TracedValue &lhs, const U &rhs) { + TRACE ("x|"); + return TracedValue (lhs.Get () | rhs); +} +template +TracedValue operator | (const U &lhs, const TracedValue &rhs) { + TRACE ("|x"); + return TracedValue (lhs | rhs.Get ()); +} + +template +TracedValue operator & (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x&x"); + return TracedValue (lhs.Get () & rhs.Get ()); +} +template +TracedValue operator & (const TracedValue &lhs, const U &rhs) { + TRACE ("x&"); + return TracedValue (lhs.Get () & rhs); +} +template +TracedValue operator & (const U &lhs, const TracedValue &rhs) { + TRACE ("&x"); + return TracedValue (lhs & rhs.Get ()); +} + +template +TracedValue operator << (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x< (lhs.Get () << rhs.Get ()); +} +template +TracedValue operator << (const TracedValue &lhs, const U &rhs) { + TRACE ("x<<"); + return TracedValue (lhs.Get () << rhs); +} +template +TracedValue operator << (const U &lhs, const TracedValue &rhs) { + TRACE ("< (lhs << rhs.Get ()); +} + +template +TracedValue operator >> (const TracedValue &lhs, const TracedValue &rhs) { + TRACE ("x>>x"); + return TracedValue (lhs.Get () >> rhs.Get ()); +} +template +TracedValue operator >> (const TracedValue &lhs, const U &rhs) { + TRACE ("x>>"); + return TracedValue (lhs.Get () >> rhs); +} +template +TracedValue operator >> (const U &lhs, const TracedValue &rhs) { + TRACE (">>x"); + return TracedValue (lhs >> rhs.Get ()); +} + + +template +TracedValue operator + (const TracedValue &lhs) { + TRACE ("(+x)"); + return TracedValue (+lhs.Get ()); +} +template +TracedValue operator - (const TracedValue &lhs) { + TRACE ("(-x)"); + return TracedValue (-lhs.Get ()); +} +template +TracedValue operator ~ (const TracedValue &lhs) { + TRACE ("(~x)"); + return TracedValue (~lhs.Get ()); +} +template +TracedValue operator ! (const TracedValue &lhs) { + TRACE ("(!x)"); + return TracedValue (!lhs.Get ()); +} + + +} // namespace ns3 + +#endif /* TRACED_VALUE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/uinteger.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/uinteger.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,65 @@ +#include "uinteger.h" +#include "fatal-error.h" +#include + +namespace ns3 { + +Uinteger::Uinteger (uint64_t value) + : m_value (value) +{} +Uinteger::Uinteger () +{} +void +Uinteger::Set (uint64_t value) +{ + m_value = value; +} +uint64_t +Uinteger::Get (void) const +{ + return m_value; +} +Uinteger::operator uint64_t () const +{ + return m_value; +} +std::ostream & operator << (std::ostream &os, const Uinteger &uinteger) +{ + os << uinteger.Get (); + return os; +} +std::istream & operator >> (std::istream &is, Uinteger &uinteger) +{ + uint64_t v; + is >> v; + uinteger.Set (v); + return is; +} + +ATTRIBUTE_CONVERTER_IMPLEMENT(Uinteger); +ATTRIBUTE_VALUE_IMPLEMENT(Uinteger); + + +Ptr MakeUintegerChecker (uint64_t min, uint64_t max) +{ + struct Checker : public AttributeChecker + { + Checker (uint64_t minValue, uint64_t maxValue) + : m_minValue (minValue), + m_maxValue (maxValue) {} + virtual bool Check (Attribute value) const { + const UintegerValue *v = value.DynCast (); + if (v == 0) + { + return false; + } + return v->Get ().Get () >= m_minValue && v->Get ().Get () <= m_maxValue; + } + uint64_t m_minValue; + uint64_t m_maxValue; + } *checker = new Checker (min, max); + return Ptr (checker, false); +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/core/uinteger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/uinteger.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,60 @@ +#ifndef UINTEGER_H +#define UINTEGER_H + +#include "attribute.h" +#include "attribute-helper.h" +#include + +namespace ns3 { + +class Uinteger +{ +public: + Uinteger (uint64_t value); + Uinteger (); + + void Set (uint64_t value); + uint64_t Get (void) const; + + operator uint64_t () const; + + ATTRIBUTE_CONVERTER_DEFINE (Uinteger); +private: + uint64_t m_value; +}; + +std::ostream & operator << (std::ostream &os, const Uinteger &uinteger); +std::istream & operator >> (std::istream &is, Uinteger &uinteger); + +ATTRIBUTE_VALUE_DEFINE (Uinteger); +ATTRIBUTE_ACCESSOR_DEFINE (Uinteger); + +template +Ptr MakeUintegerChecker (void); + +template +Ptr MakeUintegerChecker (uint64_t min); + +Ptr MakeUintegerChecker (uint64_t min, uint64_t max); + +} // namespace ns3 + +namespace ns3 { + +template +Ptr MakeUintegerChecker (void) +{ + return MakeUintegerChecker (std::numeric_limits::min (), + std::numeric_limits::max ()); +} + +template +Ptr MakeUintegerChecker (uint64_t min) +{ + return MakeUintegerChecker (min, + std::numeric_limits::max ()); +} + +} // namespace ns3 + +#endif /* UINTEGER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/core/wscript --- a/src/core/wscript Tue Feb 26 01:39:59 2008 +0100 +++ b/src/core/wscript Wed Feb 27 22:19:39 2008 +0100 @@ -31,6 +31,7 @@ 'callback-test.cc', 'log.cc', 'breakpoint.cc', + 'object-base.cc', 'ptr.cc', 'object.cc', 'test.cc', @@ -52,6 +53,20 @@ 'type-traits-test.cc', 'array-trace-resolver.cc', 'type-id-default-value.cc', + 'attribute.cc', + 'boolean.cc', + 'attribute-test.cc', + 'integer.cc', + 'uinteger.cc', + 'enum.cc', + 'double.cc', + 'string.cc', + 'object-factory.cc', + 'object-vector.cc', + 'global-value.cc', + 'traced-callback.cc', + 'trace-source-accessor.cc', + 'config.cc', ] if sys.platform == 'win32': @@ -68,6 +83,7 @@ 'system-wall-clock-ms.h', 'empty.h', 'callback.h', + 'object-base.h', 'ptr.h', 'object.h', 'log.h', @@ -95,5 +111,21 @@ 'trace-doc.h', 'int-to-type.h', 'type-id-default-value.h', + 'attribute.h', + 'attribute-accessor-helper.h', + 'boolean.h', + 'integer.h', + 'uinteger.h', + 'double.h', + 'enum.h', + 'string.h', + 'object-factory.h', + 'attribute-helper.h', + 'global-value.h', + 'traced-callback.h', + 'traced-value.h', + 'trace-source-accessor.h', + 'config.h', + 'object-vector.h', ] diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devices/csma/csma-helper.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,59 @@ +#include "csma-helper.h" + +namespace ns3 { + +CsmaHelper::CsmaHelper () +{ + m_queueFactory.SetTypeId ("DropTailQueue"); + m_deviceFactory.SetTypeId ("CsmaNetDevice"); + m_deviceChannel.SetTypeId ("CsmaChannel"); +} + +void +CsmaHelper::SetQueue (std::string type, + std::string n1, Attribute v1, + std::string n2, Attribute v2, + std::string n3, Attribute v3, + std::string n4, Attribute v4) +{ + m_queueFactory.SetTypeId (type); + m_queueFactory.Set (n1, v1); + m_queueFactory.Set (n2, v2); + m_queueFactory.Set (n3, v3); + m_queueFactory.Set (n4, v4); +} + + /** + * Set these parameters on each PointToPointNetDevice created + * by this helper. + */ +void +CsmaHelper::SetDeviceParameter (std::string n1, Attribute v1) +{ + m_deviceFactory.Set (n1, v1); +} + +void +CsmaHelper::SetChannelParameter (std::string n1, Attribute v1) +{ + m_csmaFactory.Set (n1, v1); +} + +NetDeviceContainer +CsmaHelper::Build (const NodeContainer &c) +{ + Ptr channel = m_channelFactory.Create ()->GetObject (); + return Build (c, channel); +} + +NetDeviceContainer +CsmaHelper::Build (const NodeContainer &c, Ptr channel) +{ + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++) + { + + } +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devices/csma/csma-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,38 @@ +#ifndef CSMA_HELPER_H +#define CSMA_HELPER_H + +namespace ns3 { + +class CsmaHelper +{ +public: + CsmaHelper (); + + void SetQueue (std::string type, + std::string n1 = "", Attribute v1 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute ()); + + /** + * Set these parameters on each PointToPointNetDevice created + * by this helper. + */ + void SetDeviceParameter (std::string n1, Attribute v1); + + void SetChannelParameter (std::string n1, Attribute v1); + + NetDeviceContainer Build (const NodeContainer &c); + + NetDeviceContainer Build (const NodeContainer &c, Ptr channel); + +private: + ObjectFactory m_queueFactory; + ObjectFactory m_deviceFactory; + ObjectFactory m_channelFactory; +}; + + +} // namespace ns3 + +#endif /* CSMA_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-ipv4-topology.cc --- a/src/devices/csma/csma-ipv4-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/csma/csma-ipv4-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -26,6 +26,7 @@ #include "ns3/ipv4-address.h" #include "ns3/ipv4.h" #include "ns3/queue.h" +#include "ns3/string.h" #include "csma-channel.h" #include "csma-net-device.h" @@ -42,8 +43,10 @@ Ptr q = Queue::CreateDefault (); // assume full-duplex - Ptr nd = CreateObject (node, addr, - ns3::CsmaNetDevice::IP_ARP, true, true); + Ptr nd = CreateObjectWith ("Node", node, + "Address", addr, + "EncapsulationMode", String ("IpArp")); + node->AddDevice (nd); nd->AddQueue(q); nd->Attach (channel); @@ -58,15 +61,21 @@ { Ptr q = Queue::CreateDefault (); - Ptr nd0 = CreateObject (n1, addr, - ns3::CsmaNetDevice::LLC, - true, false); + Ptr nd0 = CreateObjectWith ("Node", n1, + "Address", addr, + "EncapsulationMode", String ("Llc")); + n1->AddDevice (nd0); + nd0->SetSendEnable (true); + nd0->SetReceiveEnable (false); nd0->AddQueue(q); nd0->Attach (ch); - Ptr nd1 = CreateObject (n1, addr, - ns3::CsmaNetDevice::LLC, - false, true); + Ptr nd1 = CreateObjectWith ("Node", n1, + "Address", addr, + "EncapsulationMode", String ("Llc")); + n1->AddDevice (nd1); + nd1->SetSendEnable (false); + nd1->SetReceiveEnable (true); nd1->AddQueue(q); nd1->Attach (ch); } @@ -78,15 +87,22 @@ { Ptr q = Queue::CreateDefault (); - Ptr nd0 = CreateObject (n1, addr, - ns3::CsmaNetDevice::RAW, - true, false); + Ptr nd0 = CreateObjectWith ("Node", n1, + "Address", addr, + "EncapsulationMode", String ("Raw")); + n1->AddDevice (nd0); + nd0->SetSendEnable (true); + nd0->SetReceiveEnable (false); nd0->AddQueue(q); nd0->Attach (ch); - Ptr nd1 = CreateObject (n1, addr, - ns3::CsmaNetDevice::RAW, - false, true); + Ptr nd1 = CreateObjectWith ("Node", n1, + "Address", addr, + "EncapsulationMode", String ("Raw")); + n1->AddDevice (nd1); + nd1->SetSendEnable (false); + nd1->SetReceiveEnable (true); + nd1->AddQueue(q); nd1->Attach (ch); } diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-net-device.cc --- a/src/devices/csma/csma-net-device.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/csma/csma-net-device.cc Wed Feb 27 22:19:39 2008 +0100 @@ -22,100 +22,83 @@ #include "ns3/log.h" #include "ns3/queue.h" #include "ns3/simulator.h" -#include "ns3/composite-trace-resolver.h" -#include "csma-net-device.h" -#include "csma-channel.h" #include "ns3/ethernet-header.h" #include "ns3/ethernet-trailer.h" #include "ns3/llc-snap-header.h" #include "ns3/error-model.h" +#include "ns3/enum.h" +#include "ns3/boolean.h" +#include "ns3/trace-source-accessor.h" +#include "csma-net-device.h" +#include "csma-channel.h" + NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice"); namespace ns3 { -CsmaTraceType::CsmaTraceType (enum Type type) - : m_type (type) -{ - NS_LOG_FUNCTION; -} +NS_OBJECT_ENSURE_REGISTERED (CsmaNetDevice); -CsmaTraceType::CsmaTraceType () - : m_type (RX) -{ - NS_LOG_FUNCTION; -} - -void -CsmaTraceType::Print (std::ostream &os) const +TypeId +CsmaNetDevice::GetTypeId (void) { - switch (m_type) { - case RX: - os << "dev-rx"; - break; - case DROP: - os << "dev-drop"; - break; - } -} - -uint16_t -CsmaTraceType::GetUid (void) -{ - NS_LOG_FUNCTION; - static uint16_t uid = AllocateUid ("CsmaTraceType"); - return uid; -} - -std::string -CsmaTraceType::GetTypeName (void) const -{ - NS_LOG_FUNCTION; - return "ns3::CsmaTraceType"; + static TypeId tid = TypeId ("CsmaNetDevice") + .SetParent () + .AddConstructor () + .AddAttribute ("Node", "The node with which this device is associated", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&CsmaNetDevice::m_node), + MakePtrChecker ()) + .AddAttribute ("Address", "The address of this device.", + Mac48Address ("ff:ff:ff:ff:ff:ff"), + MakeMac48AddressAccessor (&CsmaNetDevice::m_address), + MakeMac48AddressChecker ()) + .AddAttribute ("EncapsulationMode", "The mode of link-layer encapsulation to use.", + Enum (LLC), + MakeEnumAccessor (&CsmaNetDevice::m_encapMode), + MakeEnumChecker (ETHERNET_V1, "EthernetV1", + IP_ARP, "IpArp", + RAW, "Raw", + LLC, "Llc")) + .AddAttribute ("SendEnable", "should tx be enabled ?", + Boolean (true), + MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable), + MakeBooleanChecker ()) + .AddAttribute ("ReceiveEnable", "should rx be enabled ?", + Boolean (true), + MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable), + MakeBooleanChecker ()) + .AddAttribute ("DataRate", "XXX", + DataRate (0xffffffff), + MakeDataRateAccessor (&CsmaNetDevice::m_bps), + MakeDataRateChecker ()) + .AddAttribute ("RxErrorModel", "XXX", + Ptr (0), + MakePtrAccessor (&CsmaNetDevice::m_receiveErrorModel), + MakePtrChecker ()) + .AddAttribute ("TxQueue", "XXX", + Ptr (0), + MakePtrAccessor (&CsmaNetDevice::m_queue), + MakePtrChecker ()) + .AddTraceSource ("Rx", "Receive MAC packet.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace)) + .AddTraceSource ("Drop", "Drop MAC packet.", + MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace)) + ; + return tid; } -enum CsmaTraceType::Type -CsmaTraceType::Get (void) const -{ - NS_LOG_FUNCTION; - return m_type; -} - -CsmaNetDevice::CsmaNetDevice (Ptr node) - : NetDevice (node, Mac48Address::Allocate ()), - m_bps (DataRate (0xffffffff)), - m_receiveErrorModel (0) +CsmaNetDevice::CsmaNetDevice () + : m_name (""), + m_linkUp (false), + m_mtu (0xffff) { NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << node); - m_encapMode = IP_ARP; - Init(true, true); -} - -CsmaNetDevice::CsmaNetDevice (Ptr node, Mac48Address addr, - CsmaEncapsulationMode encapMode) - : NetDevice(node, addr), - m_bps (DataRate (0xffffffff)), - m_receiveErrorModel (0) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << node); - m_encapMode = encapMode; - - Init(true, true); -} - -CsmaNetDevice::CsmaNetDevice (Ptr node, Mac48Address addr, - CsmaEncapsulationMode encapMode, - bool sendEnable, bool receiveEnable) - : NetDevice(node, addr), - m_bps (DataRate (0xffffffff)) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << node); - m_encapMode = encapMode; - - Init(sendEnable, receiveEnable); + NS_LOG_PARAMS (this); + m_txMachineState = READY; + m_tInterframeGap = Seconds(0); + m_channel = 0; } CsmaNetDevice::~CsmaNetDevice() @@ -129,43 +112,10 @@ { NS_LOG_FUNCTION; m_channel = 0; + m_node = 0; NetDevice::DoDispose (); } -// -// Assignment operator for CsmaNetDevice. -// -// This uses the non-obvious trick of taking the source net device passed by -// value instead of by reference. This causes the copy constructor to be -// invoked (where the real work is done -- see above). All we have to do -// here is to return the newly constructed net device. -// -/* -CsmaNetDevice& -CsmaNetDevice::operator= (const CsmaNetDevice nd) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << &nd); - return *this; -} -*/ - -void -CsmaNetDevice::Init(bool sendEnable, bool receiveEnable) -{ - NS_LOG_FUNCTION; - m_txMachineState = READY; - m_tInterframeGap = Seconds(0); - m_channel = 0; - m_queue = 0; - - EnableBroadcast (Mac48Address ("ff:ff:ff:ff:ff:ff")); - EnableMulticast (Mac48Address ("01:00:5e:00:00:00")); - - SetSendEnable (sendEnable); - SetReceiveEnable (receiveEnable); -} - void CsmaNetDevice::SetSendEnable (bool sendEnable) { @@ -302,58 +252,6 @@ return true; } -bool -CsmaNetDevice::DoNeedsArp (void) const -{ - NS_LOG_FUNCTION; - if ((m_encapMode == IP_ARP) || (m_encapMode == LLC)) - { - return true; - } - else - { - return false; - } -} - -bool -CsmaNetDevice::SendTo (Ptr packet, - const Address& dest, - uint16_t protocolNumber) -{ - NS_LOG_FUNCTION; - NS_LOG_LOGIC ("p=" << packet); - NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")"); - - NS_ASSERT (IsLinkUp ()); - - // Only transmit if send side of net device is enabled - if (!IsSendEnabled()) - return false; - - Mac48Address destination = Mac48Address::ConvertFrom (dest); - AddHeader(packet, destination, protocolNumber); - - // Place the packet to be sent on the send queue - if (m_queue->Enqueue(packet) == false ) - { - return false; - } - // If the device is idle, we need to start a transmission. Otherwise, - // the transmission will be started when the current packet finished - // transmission (see TransmitCompleteEvent) - if (m_txMachineState == READY) - { - // Store the next packet to be transmitted - m_currentPkt = m_queue->Dequeue (); - if (m_currentPkt != 0) - { - TransmitStart(); - } - } - return true; -} - void CsmaNetDevice::TransmitStart () { @@ -486,26 +384,6 @@ } } -Ptr -CsmaNetDevice::GetTraceResolver (void) const -{ - NS_LOG_FUNCTION; - Ptr resolver = Create (); - resolver->AddComposite ("queue", m_queue); - resolver->AddSource ("rx", - TraceDoc ("receive MAC packet", - "Ptr", "packet received"), - m_rxTrace, - CsmaTraceType (CsmaTraceType::RX)); - resolver->AddSource ("drop", - TraceDoc ("drop MAC packet", - "Ptr", "packet dropped"), - m_dropTrace, - CsmaTraceType (CsmaTraceType::DROP)); - resolver->SetParentResolver (NetDevice::GetTraceResolver ()); - return resolver; -} - bool CsmaNetDevice::Attach (Ptr ch) { @@ -540,7 +418,6 @@ NS_LOG_PARAM ("(" << em << ")"); m_receiveErrorModel = em; - AggregateObject (em); } void @@ -565,7 +442,7 @@ if (m_encapMode == RAW) { - ForwardUp (packet, 0, GetBroadcast ()); + m_rxCallback (this, packet, 0, GetBroadcast ()); m_dropTrace (packet); return; } @@ -636,12 +513,100 @@ NS_ASSERT (false); break; } - ForwardUp (packet, protocol, header.GetSource ()); + m_rxCallback (this, packet, protocol, header.GetSource ()); + } +} + +Ptr +CsmaNetDevice::GetQueue(void) const +{ + NS_LOG_FUNCTION; + return m_queue; +} + +void +CsmaNetDevice::NotifyLinkUp (void) +{ + m_linkUp = true; + if (!m_linkChangeCallback.IsNull ()) + { + m_linkChangeCallback (); } } +void +CsmaNetDevice::SetName(const std::string name) +{ + m_name = name; +} +std::string +CsmaNetDevice::GetName(void) const +{ + return m_name; +} +void +CsmaNetDevice::SetIfIndex(const uint32_t index) +{ + m_ifIndex = index; +} +uint32_t +CsmaNetDevice::GetIfIndex(void) const +{ + return m_ifIndex; +} +Ptr +CsmaNetDevice::GetChannel (void) const +{ + return m_channel; +} +Address +CsmaNetDevice::GetAddress (void) const +{ + return m_address; +} +bool +CsmaNetDevice::SetMtu (const uint16_t mtu) +{ + m_mtu = mtu; + return true; +} +uint16_t +CsmaNetDevice::GetMtu (void) const +{ + return m_mtu; +} +bool +CsmaNetDevice::IsLinkUp (void) const +{ + return m_linkUp; +} +void +CsmaNetDevice::SetLinkChangeCallback (Callback callback) +{ + m_linkChangeCallback = callback; +} +bool +CsmaNetDevice::IsBroadcast (void) const +{ + return true; +} Address -CsmaNetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const +CsmaNetDevice::GetBroadcast (void) const +{ + return Mac48Address ("ff:ff:ff:ff:ff:ff"); +} +bool +CsmaNetDevice::IsMulticast (void) const +{ + return false; +} +Address +CsmaNetDevice::GetMulticast (void) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} +Address +CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const { NS_LOG_FUNCTION; NS_LOG_PARAMS (this << multicastGroup); @@ -692,20 +657,67 @@ return etherAddr; } +bool +CsmaNetDevice::IsPointToPoint (void) const +{ + return false; +} +bool +CsmaNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) +{ + NS_LOG_FUNCTION; + NS_LOG_LOGIC ("p=" << packet); + NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")"); -Ptr -CsmaNetDevice::GetQueue(void) const -{ - NS_LOG_FUNCTION; - return m_queue; + NS_ASSERT (IsLinkUp ()); + + // Only transmit if send side of net device is enabled + if (!IsSendEnabled()) + return false; + + Mac48Address destination = Mac48Address::ConvertFrom (dest); + AddHeader(packet, destination, protocolNumber); + + // Place the packet to be sent on the send queue + if (m_queue->Enqueue(packet) == false ) + { + return false; + } + // If the device is idle, we need to start a transmission. Otherwise, + // the transmission will be started when the current packet finished + // transmission (see TransmitCompleteEvent) + if (m_txMachineState == READY) + { + // Store the next packet to be transmitted + m_currentPkt = m_queue->Dequeue (); + if (m_currentPkt != 0) + { + TransmitStart(); + } + } + return true; +} +Ptr +CsmaNetDevice::GetNode (void) const +{ + return m_node; +} +bool +CsmaNetDevice::NeedsArp (void) const +{ + if ((m_encapMode == IP_ARP) || (m_encapMode == LLC)) + { + return true; + } + else + { + return false; + } +} +void +CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) +{ + m_rxCallback = cb; } -Ptr -CsmaNetDevice::DoGetChannel(void) const -{ - NS_LOG_FUNCTION; - return m_channel; -} - - } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-net-device.h --- a/src/devices/csma/csma-net-device.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/csma/csma-net-device.h Wed Feb 27 22:19:39 2008 +0100 @@ -29,7 +29,7 @@ #include "ns3/net-device.h" #include "ns3/callback.h" #include "ns3/packet.h" -#include "ns3/callback-trace-source.h" +#include "ns3/traced-callback.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" #include "ns3/ptr.h" @@ -43,29 +43,6 @@ class ErrorModel; /** - * \brief hold in a TraceContext the type of trace source from a CsmaNetDevice - */ -class CsmaTraceType : public TraceContextElement -{ -public: - enum Type { - RX, - DROP - }; - CsmaTraceType (enum Type type); - CsmaTraceType (); - void Print (std::ostream &os) const; - static uint16_t GetUid (void); - std::string GetTypeName (void) const; - /** - * \returns the type of the trace source which generated an event. - */ - enum Type Get (void) const; -private: - enum Type m_type; -}; - -/** * \class CsmaNetDevice * \brief A Device for a Csma Network Link. * @@ -84,9 +61,10 @@ * devices * */ -class CsmaNetDevice : public NetDevice { +class CsmaNetDevice : public NetDevice +{ public: - + static TypeId GetTypeId (void); /** * Enumeration of the types of packets supported in the class. * @@ -98,7 +76,6 @@ LLC, /**< LLC packet encapsulation */ }; - CsmaNetDevice (Ptr node); /** * Construct a CsmaNetDevice * @@ -106,29 +83,10 @@ * parameter the Node to which this device is connected. Ownership of the * Node pointer is not implied and the node must not be deleted. * - * \param node the Node to which this device is connected. - * \param addr The source MAC address of the net device. - * \param pktType the type of encapsulation */ - CsmaNetDevice (Ptr node, Mac48Address addr, CsmaEncapsulationMode pktType); + CsmaNetDevice (); /** - * Construct a CsmaNetDevice - * - * This is the constructor for the CsmaNetDevice. It takes as a - * parameter the Node to which this device is connected. Ownership of the - * Node pointer is not implied and the node must not be deleted. - * - * \param node the Node to which this device is connected. - * \param addr The source MAC address of the net device. - * \param pktType the type of encapsulation - * \param sendEnable whether this device is able to send - * \param receiveEnable whether this device is able to receive - */ - CsmaNetDevice (Ptr node, Mac48Address addr, - CsmaEncapsulationMode pktType, - bool sendEnable, bool receiveEnable); - /** * Destroy a CsmaNetDevice * * This is the destructor for the CsmaNetDevice. @@ -216,6 +174,28 @@ */ void Receive (Ptr p); + bool IsSendEnabled (void); + bool IsReceiveEnabled (void); + + void SetSendEnable (bool); + void SetReceiveEnable (bool); + + + // inherited from NetDevice base class. + virtual void SetName(const std::string name); + virtual std::string GetName(void) const; + virtual void SetIfIndex(const uint32_t index); + virtual uint32_t GetIfIndex(void) const; + virtual Ptr GetChannel (void) const; + virtual Address GetAddress (void) const; + virtual bool SetMtu (const uint16_t mtu); + virtual uint16_t GetMtu (void) const; + virtual bool IsLinkUp (void) const; + virtual void SetLinkChangeCallback (Callback callback); + virtual bool IsBroadcast (void) const; + virtual Address GetBroadcast (void) const; + virtual bool IsMulticast (void) const; + virtual Address GetMulticast (void) const; /** * @brief Make and return a MAC multicast address using the provided * multicast group @@ -229,13 +209,6 @@ * to an EUI-48-based CSMA device. This MAC address is encapsulated in an * abstract Address to avoid dependencies on the exact address format. * - * A default imlementation of MakeMulticastAddress is provided, but this - * method simply NS_ASSERTS. In the case of net devices that do not support - * multicast, clients are expected to test NetDevice::IsMulticast and avoid - * attempting to map multicast packets. Subclasses of NetDevice that do - * support multicasting are expected to override this method and provide an - * implementation appropriate to the particular device. - * * @param multicastGroup The IP address for the multicast group destination * of the packet. * @return The MAC multicast Address used to send packets to the provided @@ -245,23 +218,15 @@ * @see Mac48Address * @see Address */ - Address MakeMulticastAddress (Ipv4Address multicastGroup) const; - - bool IsSendEnabled (void); - bool IsReceiveEnabled (void); - - void SetSendEnable (bool); - void SetReceiveEnable (bool); + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + virtual bool IsPointToPoint (void) const; + virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual Ptr GetNode (void) const; + virtual bool NeedsArp (void) const; + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); protected: - virtual bool DoNeedsArp (void) const; virtual void DoDispose (void); - /** - * Create a Trace Resolver for events in the net device. - * (NOT TESTED) - * @see class TraceResolver - */ - virtual Ptr GetTraceResolver (void) const; /** * Get a copy of the attached Queue. @@ -273,15 +238,6 @@ */ Ptr GetQueue (void) const; /** - * Get a copy of the attached Channel - * - * This method is provided for any derived class that may need to get - * direct access to the connected channel - * - * \return a pointer to the channel - */ - virtual Ptr DoGetChannel (void) const; - /** * Adds the necessary headers and trailers to a packet of data in order to * respect the packet type * @@ -312,22 +268,6 @@ * Initializes variablea when construction object. */ void Init (bool sendEnable, bool receiveEnable); - /** - * Send a Packet on the Csma network - * - * This method does not use a destination address since all packets - * are broadcast to all NetDevices attached to the channel. Packet - * should contain all needed headers at this time. - * - * If the device is ready to transmit, the next packet is read off - * of the queue and stored locally until it has been transmitted. - * - * \param p a reference to the packet to send - * \param dest destination address - * \param protocolNumber -- this parameter is not used here - * \return true if success, false on failure - */ - virtual bool SendTo (Ptr p, const Address& dest, uint16_t protocolNumber); /** * Start Sending a Packet Down the Wire. @@ -388,6 +328,7 @@ * */ void TransmitAbort (void); + void NotifyLinkUp (void); /** * Device ID returned by the attached functions. It is used by the @@ -478,9 +419,17 @@ * @see class CallBackTraceSource * @see class TraceResolver */ - CallbackTraceSource > m_rxTrace; - CallbackTraceSource > m_dropTrace; + TracedCallback > m_rxTrace; + TracedCallback > m_dropTrace; + Ptr m_node; + Mac48Address m_address; + NetDevice::ReceiveCallback m_rxCallback; + uint32_t m_ifIndex; + std::string m_name; + bool m_linkUp; + Callback m_linkChangeCallback; + uint16_t m_mtu; }; }; // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/devices/csma/csma-topology.cc --- a/src/devices/csma/csma-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/csma/csma-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -46,10 +46,11 @@ CsmaTopology::AddCsmaEthernetNode( Ptr n1, Ptr ch, - MacAddress addr) + Mac48Address addr) { - Ptr nd1 = CreateObject (n1, addr, - ns3::CsmaNetDevice::ETHERNET_V1); + Ptr nd1 = CreateObjectWith ("Node", Ptr (n1), + "Address", addr, + "EncapsulationMode", "EthernetV1"); Ptr q = Queue::CreateDefault (); nd1->AddQueue(q); @@ -60,8 +61,8 @@ Ptr CsmaTopology::ConnectPacketSocket(Ptr app, - Ptr ndSrc, - Ptr ndDest) + Ptr ndSrc, + Ptr ndDest) { Ptr socket = CreateObject (); socket->Bind(ndSrc); diff -r d64b1561b1c2 -r e667dc0f350e src/devices/point-to-point/point-to-point-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devices/point-to-point/point-to-point-helper.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,53 @@ +#include "point-to-point-helper.h" +#include "point-to-point-net-device.h" +#include "point-to-point-channel.h" +#include "ns3/queue.h" + +namespace ns3 { + + +PointToPointHelper::PointToPointHelper () +{} + +void +PointToPointHelper::SetQueue (std::string type, + std::string n1, Attribute v1, + std::string n2, Attribute v2, + std::string n3, Attribute v3, + std::string n4, Attribute v4) +{ + m_queueFactory.SetTypeId (type); + m_queueFactory.Set (n1, v1); + m_queueFactory.Set (n2, v2); + m_queueFactory.Set (n3, v3); + m_queueFactory.Set (n4, v4); +} + +NetDeviceContainer +PointToPointHelper::Build (NodeContainer c) +{ + NS_ASSERT (c.GetN () == 2); + return Build (c.Get (0), c.Get (1)); +} +NetDeviceContainer +PointToPointHelper::Build (Ptr a, Ptr b) +{ + NetDeviceContainer container; + + Ptr devA = CreateObject (a); + Ptr queueA = m_queueFactory.Create ()->GetObject (); + devA->AddQueue (queueA); + Ptr devB = CreateObject (b); + Ptr queueB = m_queueFactory.Create ()->GetObject (); + devB->AddQueue (queueB); + Ptr channel = CreateObject (); + devA->Attach (channel); + devB->Attach (channel); + container.Add (devA); + container.Add (devB); + + return container; +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/devices/point-to-point/point-to-point-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/devices/point-to-point/point-to-point-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,42 @@ +#ifndef POINT_TO_POINT_HELPER_H +#define POINT_TO_POINT_HELPER_H + +#include "ns3/object-factory.h" +#include "ns3/net-device-container.h" +#include "ns3/node-container.h" +#include + +namespace ns3 { + +class PointToPointHelper +{ +public: + // by default, create queues of type DropTailQueue. + PointToPointHelper (); + + void SetQueue (std::string type, + std::string n1 = "", Attribute v1 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute ()); + + /** + * Set these parameters on each PointToPointNetDevice created + * by this helper. + */ + void SetDeviceParameters (std::string n1, Attribute v1, + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute ()); + + NetDeviceContainer Build (NodeContainer c); + NetDeviceContainer Build (Ptr a, Ptr b); + +private: + ObjectFactory m_queueFactory; +}; + + +} // namespace ns3 + +#endif /* POINT_TO_POINT_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/devices/point-to-point/point-to-point-net-device.cc --- a/src/devices/point-to-point/point-to-point-net-device.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/point-to-point/point-to-point-net-device.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,10 +23,10 @@ #include "ns3/log.h" #include "ns3/queue.h" #include "ns3/simulator.h" -#include "ns3/composite-trace-resolver.h" #include "ns3/mac48-address.h" #include "ns3/llc-snap-header.h" #include "ns3/error-model.h" +#include "ns3/trace-source-accessor.h" #include "point-to-point-net-device.h" #include "point-to-point-channel.h" @@ -34,91 +34,63 @@ namespace ns3 { -DataRateDefaultValue PointToPointNetDevice::g_defaultRate( - "PointToPointLinkDataRate", - "The default data rate for point to point links", - DataRate ("10Mb/s")); +NS_OBJECT_ENSURE_REGISTERED (PointToPointNetDevice); -PointToPointTraceType::PointToPointTraceType (enum Type type) - : m_type (type) +TypeId +PointToPointNetDevice::GetTypeId (void) { - NS_LOG_FUNCTION; -} -PointToPointTraceType::PointToPointTraceType () - : m_type (RX) -{ - NS_LOG_FUNCTION; + static TypeId tid = TypeId ("PointToPointNetDevice") + .SetParent () + .AddConstructor () + .AddAttribute ("Node", "The node with which this device is associated", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&PointToPointNetDevice::m_node), + MakePtrChecker ()) + .AddAttribute ("Address", "The address of this device.", + Mac48Address ("ff:ff:ff:ff:ff:ff"), + MakeMac48AddressAccessor (&PointToPointNetDevice::m_address), + MakeMac48AddressChecker ()) + .AddAttribute ("DataRate", "The default data rate for point to point links", + DataRate ("10Mb/s"), + MakeDataRateAccessor (&PointToPointNetDevice::m_bps), + MakeDataRateChecker ()) + .AddAttribute ("RxErrorModel", "XXX", + Ptr (0), + MakePtrAccessor (&PointToPointNetDevice::m_receiveErrorModel), + MakePtrChecker ()) + .AddAttribute ("TxQueue", "XXX", + Ptr (0), + MakePtrAccessor (&PointToPointNetDevice::m_queue), + MakePtrChecker ()) + .AddAttribute ("InterframeGap", "XXX", + Seconds (0.0), + MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap), + MakeTimeChecker ()) + .AddTraceSource ("Rx", "Receive MAC packet.", + MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace)) + .AddTraceSource ("Drop", "Drop MAC packet.", + MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace)) + + ; + return tid; } -void -PointToPointTraceType::Print (std::ostream &os) const -{ - switch (m_type) { - case RX: - os << "dev-rx"; - break; - case DROP: - os << "dev-drop"; - break; - } -} -uint16_t -PointToPointTraceType::GetUid (void) -{ - NS_LOG_FUNCTION; - static uint16_t uid = AllocateUid ("PointToPointTraceType"); - return uid; -} - -std::string -PointToPointTraceType::GetTypeName (void) const +PointToPointNetDevice::PointToPointNetDevice () +: + m_txMachineState (READY), + m_channel (0), + m_name (""), + m_linkUp (false), + m_mtu (0xffff) { NS_LOG_FUNCTION; - return "ns3::PointToPointTraceType"; -} - -enum PointToPointTraceType::Type -PointToPointTraceType::Get (void) const -{ - NS_LOG_FUNCTION; - return m_type; + NS_LOG_PARAMS (this); } -PointToPointNetDevice::PointToPointNetDevice (Ptr node, - const DataRate& rate) -: - NetDevice(node, Mac48Address::Allocate ()), - m_txMachineState (READY), - m_bps (rate), - m_tInterframeGap (Seconds(0)), - m_channel (0), - m_queue (0), - m_rxTrace (), - m_dropTrace (), - m_receiveErrorModel (0) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << node); -// -// XXX BUGBUG -// -// You _must_ support broadcast to get any sort of packet from the ARP layer. -// - EnableBroadcast (Mac48Address ("ff:ff:ff:ff:ff:ff")); -// -// We want to allow multicast packets to flow across this link -// - EnableMulticast (Mac48Address ("01:00:5e:00:00:00")); - EnablePointToPoint(); -} - -PointToPointNetDevice::~PointToPointNetDevice() -{ - NS_LOG_FUNCTION; - m_queue = 0; - m_receiveErrorModel = 0; -} +PointToPointNetDevice::~PointToPointNetDevice () +{} void PointToPointNetDevice::AddHeader(Ptr p, uint16_t protocolNumber) @@ -144,7 +116,9 @@ void PointToPointNetDevice::DoDispose() { NS_LOG_FUNCTION; + m_node = 0; m_channel = 0; + m_receiveErrorModel = 0; NetDevice::DoDispose (); } @@ -163,40 +137,7 @@ m_tInterframeGap = t; } -bool PointToPointNetDevice::SendTo (Ptr packet, const Address& dest, - uint16_t protocolNumber) -{ - NS_LOG_FUNCTION; - NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest); - NS_LOG_LOGIC ("UID is " << packet->GetUid ()); - - // GFR Comment. Why is this an assertion? Can't a link legitimately - // "go down" during the simulation? Shouldn't we just wait for it - // to come back up? - NS_ASSERT (IsLinkUp ()); - AddHeader(packet, protocolNumber); - -// -// This class simulates a point to point device. In the case of a serial -// link, this means that we're simulating something like a UART. -// -// -// If there's a transmission in progress, we enque the packet for later -// transmission; otherwise we send it now. - if (m_txMachineState == READY) - { -// We still enqueue and dequeue it to hit the tracing hooks - m_queue->Enqueue (packet); - packet = m_queue->Dequeue (); - return TransmitStart (packet); - } - else - { - return m_queue->Enqueue(packet); - } -} - - bool +bool PointToPointNetDevice::TransmitStart (Ptr p) { NS_LOG_FUNCTION; @@ -240,26 +181,6 @@ TransmitStart(p); } -Ptr -PointToPointNetDevice::GetTraceResolver (void) const -{ - NS_LOG_FUNCTION; - Ptr resolver = Create (); - resolver->AddComposite ("queue", m_queue); - resolver->AddSource ("rx", - TraceDoc ("receive MAC packet", - "Ptr", "packet received"), - m_rxTrace, - PointToPointTraceType (PointToPointTraceType::RX)); - resolver->AddSource ("drop", - TraceDoc ("drop MAC packet", - "Ptr", "packet dropped"), - m_dropTrace, - PointToPointTraceType (PointToPointTraceType::DROP)); - resolver->SetParentResolver (NetDevice::GetTraceResolver ()); - return resolver; -} - bool PointToPointNetDevice::Attach (Ptr ch) { @@ -320,7 +241,7 @@ { m_rxTrace (packet); ProcessHeader(packet, protocol); - ForwardUp (packet, protocol, GetBroadcast ()); + m_rxCallback (this, packet, protocol, GetBroadcast ()); } } @@ -330,16 +251,144 @@ return m_queue; } -Ptr PointToPointNetDevice::DoGetChannel(void) const -{ - NS_LOG_FUNCTION; - return m_channel; +void +PointToPointNetDevice::NotifyLinkUp (void) +{ + m_linkUp = true; + if (!m_linkChangeCallback.IsNull ()) + { + m_linkChangeCallback (); + } } -bool PointToPointNetDevice::DoNeedsArp (void) const +void +PointToPointNetDevice::SetName(const std::string name) +{ + m_name = name; +} +std::string +PointToPointNetDevice::GetName(void) const +{ + return m_name; +} +void +PointToPointNetDevice::SetIfIndex(const uint32_t index) +{ + m_ifIndex = index; +} +uint32_t +PointToPointNetDevice::GetIfIndex(void) const +{ + return m_ifIndex; +} +Ptr +PointToPointNetDevice::GetChannel (void) const +{ + return m_channel; +} +Address +PointToPointNetDevice::GetAddress (void) const { - NS_LOG_FUNCTION; + return m_address; +} +bool +PointToPointNetDevice::SetMtu (const uint16_t mtu) +{ + m_mtu = mtu; + return true; +} +uint16_t +PointToPointNetDevice::GetMtu (void) const +{ + return m_mtu; +} +bool +PointToPointNetDevice::IsLinkUp (void) const +{ + return m_linkUp; +} +void +PointToPointNetDevice::SetLinkChangeCallback (Callback callback) +{ + m_linkChangeCallback = callback; +} +bool +PointToPointNetDevice::IsBroadcast (void) const +{ + return true; +} +Address +PointToPointNetDevice::GetBroadcast (void) const +{ + return Mac48Address ("ff:ff:ff:ff:ff:ff"); +} +bool +PointToPointNetDevice::IsMulticast (void) const +{ return false; } +Address +PointToPointNetDevice::GetMulticast (void) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} +Address +PointToPointNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} +bool +PointToPointNetDevice::IsPointToPoint (void) const +{ + return true; +} +bool +PointToPointNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) +{ + NS_LOG_FUNCTION; + NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest); + NS_LOG_LOGIC ("UID is " << packet->GetUid ()); + + // GFR Comment. Why is this an assertion? Can't a link legitimately + // "go down" during the simulation? Shouldn't we just wait for it + // to come back up? + NS_ASSERT (IsLinkUp ()); + AddHeader(packet, protocolNumber); + +// +// This class simulates a point to point device. In the case of a serial +// link, this means that we're simulating something like a UART. +// +// +// If there's a transmission in progress, we enque the packet for later +// transmission; otherwise we send it now. + if (m_txMachineState == READY) + { +// We still enqueue and dequeue it to hit the tracing hooks + m_queue->Enqueue (packet); + packet = m_queue->Dequeue (); + return TransmitStart (packet); + } + else + { + return m_queue->Enqueue(packet); + } +} +Ptr +PointToPointNetDevice::GetNode (void) const +{ + return m_node; +} +bool +PointToPointNetDevice::NeedsArp (void) const +{ + return false; +} +void +PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) +{ + m_rxCallback = cb; +} + } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/devices/point-to-point/point-to-point-net-device.h --- a/src/devices/point-to-point/point-to-point-net-device.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/point-to-point/point-to-point-net-device.h Wed Feb 27 22:19:39 2008 +0100 @@ -27,11 +27,11 @@ #include "ns3/net-device.h" #include "ns3/callback.h" #include "ns3/packet.h" -#include "ns3/callback-trace-source.h" +#include "ns3/traced-callback.h" #include "ns3/nstime.h" #include "ns3/data-rate.h" -#include "ns3/default-value.h" #include "ns3/ptr.h" +#include "ns3/mac48-address.h" namespace ns3 { @@ -40,29 +40,6 @@ class ErrorModel; /** - * \brief hold in a TraceContext the type of trace source from a PointToPointNetDevice - */ -class PointToPointTraceType : public TraceContextElement -{ -public: - enum Type { - RX, - DROP - }; - PointToPointTraceType (enum Type type); - PointToPointTraceType (); - void Print (std::ostream &os) const; - static uint16_t GetUid (void); - std::string GetTypeName (void) const; - /** - * \returns the type of the trace source which generated an event. - */ - enum Type Get (void) const; -private: - enum Type m_type; -}; - -/** * \class PointToPointNetDevice * \brief A Device for a Point to Point Network Link. * @@ -74,8 +51,11 @@ * include a queue, data rate, and interframe transmission gap (the * propagation delay is set in the PointToPointChannel). */ -class PointToPointNetDevice : public NetDevice { +class PointToPointNetDevice : public NetDevice +{ public: + static TypeId GetTypeId (void); + /** * Construct a PointToPointNetDevice * @@ -84,11 +64,8 @@ * as well as an optional DataRate object. * * @see PointToPointTopology::AddPointToPointLink () - * @param node the Node to which this device is connected. - * @param rate (optional) DataRate object */ - PointToPointNetDevice (Ptr node, - const DataRate& rate = g_defaultRate.GetValue()); + PointToPointNetDevice (); /** * Destroy a PointToPointNetDevice * @@ -168,13 +145,29 @@ */ void Receive (Ptr p); + // inherited from NetDevice base class. + virtual void SetName(const std::string name); + virtual std::string GetName(void) const; + virtual void SetIfIndex(const uint32_t index); + virtual uint32_t GetIfIndex(void) const; + virtual Ptr GetChannel (void) const; + virtual Address GetAddress (void) const; + virtual bool SetMtu (const uint16_t mtu); + virtual uint16_t GetMtu (void) const; + virtual bool IsLinkUp (void) const; + virtual void SetLinkChangeCallback (Callback callback); + virtual bool IsBroadcast (void) const; + virtual Address GetBroadcast (void) const; + virtual bool IsMulticast (void) const; + virtual Address GetMulticast (void) const; + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + virtual bool IsPointToPoint (void) const; + virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual Ptr GetNode (void) const; + virtual bool NeedsArp (void) const; + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + private: - /** - * Create a Trace Resolver for events in the net device. - * - * @see class TraceResolver - */ - virtual Ptr GetTraceResolver (void) const; virtual void DoDispose (void); /** @@ -188,28 +181,6 @@ */ Ptr GetQueue(void) const; - /** - * Get a copy of the attached Channel - * - * This method is provided for any derived class that may need to get - * direct access to the connected channel - * - * @see PointToPointChannel - * @returns a pointer to the channel - */ - virtual Ptr DoGetChannel(void) const; - - /** - * Set a new default data rate - */ - static void SetDefaultRate(const DataRate&); - - /** - * Get the current default rate. - * @returns a const reference to current default - */ - static const DataRate& GetDefaultRate(); - private: /** * Adds the necessary headers and trailers to a packet of data in order to @@ -224,21 +195,6 @@ */ bool ProcessHeader(Ptr p, uint16_t& param); /** - * Send a Packet Down the Wire. - * - * The SendTo method is defined as the standard way that the level three - * protocol uses to tell a NetDevice to send a packet. SendTo is declared - * as abstract in the NetDevice class and we declare it here. - * - * @see NetDevice - * @param p a reference to the packet to send - * @param dest a reference to the Address of the destination device - * @param protocolNumber Protocol Number used to find protocol touse - * @returns true if success, false on failure - */ - virtual bool SendTo (Ptr p, const Address& dest, - uint16_t protocolNumber); - /** * Start Sending a Packet Down the Wire. * * The TransmitStart method is the method that is used internally in the @@ -262,7 +218,8 @@ * */ void TransmitComplete(void); - virtual bool DoNeedsArp (void) const; + void NotifyLinkUp (void); + /** * Enumeration of the states of the transmit machine of the net device. */ @@ -309,7 +266,7 @@ * @see class CallBackTraceSource * @see class TraceResolver */ - CallbackTraceSource > m_rxTrace; + TracedCallback > m_rxTrace; /** * The trace source for the packet drop events that the device can * fire. @@ -317,19 +274,24 @@ * @see class CallBackTraceSource * @see class TraceResolver */ - CallbackTraceSource > m_dropTrace; - /** - * Default data rate. Used for all newly created p2p net devices - */ - static DataRateDefaultValue g_defaultRate; + TracedCallback > m_dropTrace; /** * Error model for receive packet events */ Ptr m_receiveErrorModel; + + Ptr m_node; + Mac48Address m_address; + NetDevice::ReceiveCallback m_rxCallback; + uint32_t m_ifIndex; + std::string m_name; + bool m_linkUp; + Callback m_linkChangeCallback; + uint16_t m_mtu; }; -}; // namespace ns3 +} // namespace ns3 #endif // POINT_TO_POINT_NET_DEVICE_H diff -r d64b1561b1c2 -r e667dc0f350e src/devices/point-to-point/point-to-point-topology.cc --- a/src/devices/point-to-point/point-to-point-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/point-to-point/point-to-point-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -47,13 +47,17 @@ { Ptr channel = CreateObject (bps, delay); - Ptr net1 = CreateObject (n1); + Ptr net1 = CreateObjectWith ("Node", n1, + "Address", Mac48Address::Allocate ()); + n1->AddDevice (net1); Ptr q = Queue::CreateDefault (); net1->AddQueue(q); net1->Attach (channel); - Ptr net2 = CreateObject (n2); + Ptr net2 = CreateObjectWith ("Node", n2, + "Address", Mac48Address::Allocate ()); + n2->AddDevice (net2); q = Queue::CreateDefault (); net2->AddQueue(q); diff -r d64b1561b1c2 -r e667dc0f350e src/devices/wifi/propagation-loss-model.cc --- a/src/devices/wifi/propagation-loss-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/wifi/propagation-loss-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -286,8 +286,12 @@ * * rx = rx0(tx) - 10 * n * log (d/d0) */ - static Ptr zero = CreateObject (Vector (0.0, 0.0, 0.0)); - static Ptr reference = CreateObject (Vector (m_referenceDistance, 0.0, 0.0)); + static Ptr zero = + CreateObjectWith ("position", + Vector (0.0, 0.0, 0.0)); + static Ptr reference = + CreateObjectWith ("position", + Vector (m_referenceDistance, 0.0, 0.0)); double rx0 = m_reference->GetRxPower (txPowerDbm, zero, reference); double pathLossDb = 10 * m_exponent * log10 (distance / m_referenceDistance); double rxPowerDbm = rx0 - pathLossDb; diff -r d64b1561b1c2 -r e667dc0f350e src/devices/wifi/wifi-net-device.cc --- a/src/devices/wifi/wifi-net-device.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/wifi/wifi-net-device.cc Wed Feb 27 22:19:39 2008 +0100 @@ -159,14 +159,12 @@ ***************************************************************/ -WifiNetDevice::WifiNetDevice (Ptr node) - : NetDevice (node, Mac48Address::Allocate ()) -{ - Construct (); -} WifiNetDevice::WifiNetDevice (Ptr node, Mac48Address self) - : NetDevice (node, self) + : m_node (node), + m_address (self), + m_name (""), + m_linkUp (false) { Construct (); } @@ -177,9 +175,7 @@ void WifiNetDevice::Construct (void) { - SetMtu (2300); - EnableBroadcast (Mac48Address ("ff:ff:ff:ff:ff:ff")); - + m_mtu = 2300; // the physical layer. m_phy = Create (this); @@ -313,21 +309,6 @@ m_phy->SetChannel (channel); NotifyAttached (); } -bool -WifiNetDevice::SendTo (Ptr packet, const Address &to, uint16_t protocolNumber) -{ - NS_ASSERT (Mac48Address::IsMatchingType (to)); - - Mac48Address realTo = Mac48Address::ConvertFrom (to); - - LlcSnapHeader llc; - llc.SetType (protocolNumber); - packet->AddHeader (llc); - - m_txLogger (packet, realTo); - - return DoSendTo (packet, realTo); -} void WifiNetDevice::DoForwardUp (Ptr packet, const Mac48Address &from) { @@ -335,7 +316,7 @@ LlcSnapHeader llc; packet->RemoveHeader (llc); - NetDevice::ForwardUp (packet, llc.GetType (), from); + m_rxCallback (this, packet, llc.GetType (), from); } Mac48Address WifiNetDevice::GetSelfAddress (void) const @@ -344,22 +325,11 @@ Mac48Address self = Mac48Address::ConvertFrom (GetAddress ()); return self; } -bool -WifiNetDevice::DoNeedsArp (void) const -{ - return true; -} -Ptr -WifiNetDevice::DoGetChannel (void) const -{ - return m_channel; -} void WifiNetDevice::DoDispose (void) { - // chain up. - NetDevice::DoDispose (); // cleanup local + m_node = 0; m_channel = 0; delete m_stations; delete m_rxMiddle; @@ -374,6 +344,136 @@ m_rxMiddle = 0; m_txMiddle = 0; m_parameters = 0; + // chain up. + NetDevice::DoDispose (); +} + +void +WifiNetDevice::NotifyLinkUp (void) +{ + m_linkUp = true; + if (!m_linkChangeCallback.IsNull ()) + { + m_linkChangeCallback (); + } +} +void +WifiNetDevice::NotifyLinkDown (void) +{ + m_linkUp = false; + m_linkChangeCallback (); +} + +void +WifiNetDevice::SetName(const std::string name) +{ + m_name = name; +} +std::string +WifiNetDevice::GetName(void) const +{ + return m_name; +} +void +WifiNetDevice::SetIfIndex(const uint32_t index) +{ + m_ifIndex = index; +} +uint32_t +WifiNetDevice::GetIfIndex(void) const +{ + return m_ifIndex; +} +Ptr +WifiNetDevice::GetChannel (void) const +{ + return m_channel; +} +Address +WifiNetDevice::GetAddress (void) const +{ + return m_address; +} +bool +WifiNetDevice::SetMtu (const uint16_t mtu) +{ + m_mtu = mtu; + return true; +} +uint16_t +WifiNetDevice::GetMtu (void) const +{ + return m_mtu; +} +bool +WifiNetDevice::IsLinkUp (void) const +{ + return m_linkUp; +} +void +WifiNetDevice::SetLinkChangeCallback (Callback callback) +{ + m_linkChangeCallback = callback; +} +bool +WifiNetDevice::IsBroadcast (void) const +{ + return true; +} +Address +WifiNetDevice::GetBroadcast (void) const +{ + return Mac48Address ("ff:ff:ff:ff:ff:ff"); +} +bool +WifiNetDevice::IsMulticast (void) const +{ + return false; +} +Address +WifiNetDevice::GetMulticast (void) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} +Address +WifiNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const +{ + return Mac48Address ("01:00:5e:00:00:00"); +} +bool +WifiNetDevice::IsPointToPoint (void) const +{ + return false; +} +bool +WifiNetDevice::Send(Ptr packet, const Address& to, uint16_t protocolNumber) +{ + NS_ASSERT (Mac48Address::IsMatchingType (to)); + + Mac48Address realTo = Mac48Address::ConvertFrom (to); + + LlcSnapHeader llc; + llc.SetType (protocolNumber); + packet->AddHeader (llc); + + m_txLogger (packet, realTo); + + return DoSendTo (packet, realTo); +} +Ptr +WifiNetDevice::GetNode (void) const +{ + return m_node; +} +bool +WifiNetDevice::NeedsArp (void) const +{ + return true; +} +void +WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) +{ + m_rxCallback = cb; } @@ -381,11 +481,6 @@ * Adhoc code *****************************************************/ -AdhocWifiNetDevice::AdhocWifiNetDevice (Ptr node) - : WifiNetDevice (node) -{ - DoConstruct (); -} AdhocWifiNetDevice::AdhocWifiNetDevice (Ptr node, Mac48Address self) : WifiNetDevice (node, self) { @@ -462,11 +557,6 @@ * STA code *****************************************************/ -NqstaWifiNetDevice::NqstaWifiNetDevice (Ptr node) - : WifiNetDevice (node) -{ - DoConstruct (); -} NqstaWifiNetDevice::NqstaWifiNetDevice (Ptr node, Mac48Address self) : WifiNetDevice (node, self) { @@ -526,13 +616,13 @@ void NqstaWifiNetDevice::Associated (void) { - NetDevice::NotifyLinkUp (); + WifiNetDevice::NotifyLinkUp (); } void NqstaWifiNetDevice::DisAssociated (void) { - NetDevice::NotifyLinkDown (); + WifiNetDevice::NotifyLinkDown (); } void NqstaWifiNetDevice::DoDispose (void) @@ -560,11 +650,6 @@ *****************************************************/ -NqapWifiNetDevice::NqapWifiNetDevice (Ptr node) - : WifiNetDevice (node) -{ - DoConstruct (); -} NqapWifiNetDevice::NqapWifiNetDevice (Ptr node, Mac48Address self) : WifiNetDevice (node, self) { diff -r d64b1561b1c2 -r e667dc0f350e src/devices/wifi/wifi-net-device.h --- a/src/devices/wifi/wifi-net-device.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/wifi/wifi-net-device.h Wed Feb 27 22:19:39 2008 +0100 @@ -98,14 +98,32 @@ */ virtual Ssid GetSsid (void) const = 0; + // inherited from NetDevice base class. + virtual void SetName(const std::string name); + virtual std::string GetName(void) const; + virtual void SetIfIndex(const uint32_t index); + virtual uint32_t GetIfIndex(void) const; + virtual Ptr GetChannel (void) const; + virtual Address GetAddress (void) const; + virtual bool SetMtu (const uint16_t mtu); + virtual uint16_t GetMtu (void) const; + virtual bool IsLinkUp (void) const; + virtual void SetLinkChangeCallback (Callback callback); + virtual bool IsBroadcast (void) const; + virtual Address GetBroadcast (void) const; + virtual bool IsMulticast (void) const; + virtual Address GetMulticast (void) const; + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; + virtual bool IsPointToPoint (void) const; + virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual Ptr GetNode (void) const; + virtual bool NeedsArp (void) const; + virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + private: class PhyListener; class NavListener; - // inherited from NetDevice - virtual bool DoNeedsArp (void) const; - virtual Ptr DoGetChannel (void) const; - virtual bool SendTo (Ptr packet, const Address &to, uint16_t protocolNumber); // defined for children virtual void NotifyAttached (void) = 0; virtual bool DoSendTo (Ptr packet, const Mac48Address &to) = 0; @@ -115,14 +133,15 @@ CallbackTraceSource, Mac48Address> m_rxLogger; CallbackTraceSource, Mac48Address> m_txLogger; protected: - // inherited from Object - virtual Ptr GetTraceResolver (void) const; - WifiNetDevice (Ptr node); WifiNetDevice (Ptr node, Mac48Address self); void DoForwardUp (Ptr packet, const Mac48Address &from); Ptr CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const; + void NotifyLinkUp (void); + void NotifyLinkDown (void); // inherited from Object virtual void DoDispose (void); + // inherited from Object + virtual Ptr GetTraceResolver (void) const; Ptr m_channel; Ptr m_phy; @@ -134,6 +153,15 @@ DcfManager *m_manager; PhyListener *m_phyListener; NavListener *m_navListener; + + Ptr m_node; + Mac48Address m_address; + NetDevice::ReceiveCallback m_rxCallback; + uint32_t m_ifIndex; + std::string m_name; + bool m_linkUp; + Callback m_linkChangeCallback; + uint16_t m_mtu; }; /** @@ -144,7 +172,6 @@ */ class AdhocWifiNetDevice : public WifiNetDevice { public: - AdhocWifiNetDevice (Ptr node); AdhocWifiNetDevice (Ptr node, Mac48Address self); virtual ~AdhocWifiNetDevice (); @@ -184,7 +211,6 @@ /** * The ssid is initialized from \valueref{WifiSsid}. */ - NqstaWifiNetDevice (Ptr node); NqstaWifiNetDevice (Ptr node, Mac48Address self); virtual ~NqstaWifiNetDevice (); diff -r d64b1561b1c2 -r e667dc0f350e src/devices/wifi/wifi-phy.cc --- a/src/devices/wifi/wifi-phy.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/devices/wifi/wifi-phy.cc Wed Feb 27 22:19:39 2008 +0100 @@ -30,6 +30,7 @@ #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/composite-trace-resolver.h" +#include "ns3/object-base.h" #include NS_LOG_COMPONENT_DEFINE ("WifiPhy"); @@ -76,7 +77,8 @@ * Phy event class ****************************************************************/ -class RxEvent { +class RxEvent : public ObjectBase +{ public: RxEvent (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble, diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/arp-l3-protocol.cc --- a/src/internet-node/arp-l3-protocol.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/arp-l3-protocol.cc Wed Feb 27 22:19:39 2008 +0100 @@ -41,12 +41,17 @@ ArpL3Protocol::GetTypeId (void) { static TypeId tid = TypeId ("ArpL3Protocol") - .SetParent (); + .SetParent () + .AddAttribute ("Node", "The node to which this protocol is associated.", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&ArpL3Protocol::m_node), + MakePtrChecker ()) + ; return tid; } -ArpL3Protocol::ArpL3Protocol (Ptr node) - : m_node (node) +ArpL3Protocol::ArpL3Protocol () { NS_LOG_FUNCTION; } diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/arp-l3-protocol.h --- a/src/internet-node/arp-l3-protocol.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/arp-l3-protocol.h Wed Feb 27 22:19:39 2008 +0100 @@ -46,7 +46,7 @@ * \brief Constructor * \param node The node which this ARP object is associated with */ - ArpL3Protocol (Ptr node); + ArpL3Protocol (); virtual ~ArpL3Protocol (); /** * \brief Recieve a packet diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/internet-node.cc --- a/src/internet-node/internet-node.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/internet-node.cc Wed Feb 27 22:19:39 2008 +0100 @@ -21,7 +21,6 @@ // Implementation of the InternetNode class for ns3. // George F. Riley, Georgia Tech, Fall 2006 -#include "ns3/composite-trace-resolver.h" #include "ns3/net-device.h" #include "ns3/callback.h" @@ -53,8 +52,8 @@ void InternetNode::Construct (void) { - Ptr ipv4 = CreateObject (this); - Ptr arp = CreateObject (this); + Ptr ipv4 = CreateObjectWith ("Node", Ptr (this)); + Ptr arp = CreateObjectWith ("Node", Ptr (this)); // XXX remove the PeekPointer below. RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, PeekPointer (ipv4)), Ipv4L3Protocol::PROT_NUMBER, 0); @@ -62,9 +61,9 @@ ArpL3Protocol::PROT_NUMBER, 0); - Ptr ipv4L4Demux = CreateObject (this); - Ptr udp = CreateObject (this); - Ptr tcp = CreateObject (this); + Ptr ipv4L4Demux = CreateObjectWith ("Node", Ptr (this)); + Ptr udp = CreateObjectWith ("Node", Ptr (this)); + Ptr tcp = CreateObjectWith ("Node", Ptr (this)); ipv4L4Demux->Insert (udp); ipv4L4Demux->Insert (tcp); @@ -81,16 +80,6 @@ Object::AggregateObject (ipv4L4Demux); } -Ptr -InternetNode::GetTraceResolver () const -{ - Ptr resolver = Create (); - Ptr ipv4 = GetObject (); - resolver->AddComposite ("ipv4", ipv4); - resolver->SetParentResolver (Node::GetTraceResolver ()); - return resolver; -} - void InternetNode::DoDispose() { diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/internet-node.h --- a/src/internet-node/internet-node.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/internet-node.h Wed Feb 27 22:19:39 2008 +0100 @@ -63,7 +63,6 @@ protected: virtual void DoDispose(void); - virtual Ptr GetTraceResolver (void) const; private: void Construct (void); }; diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l3-protocol.cc --- a/src/internet-node/ipv4-l3-protocol.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l3-protocol.cc Wed Feb 27 22:19:39 2008 +0100 @@ -21,12 +21,14 @@ #include "ns3/packet.h" #include "ns3/log.h" -#include "ns3/composite-trace-resolver.h" #include "ns3/callback.h" #include "ns3/ipv4-address.h" #include "ns3/ipv4-route.h" #include "ns3/node.h" #include "ns3/net-device.h" +#include "ns3/uinteger.h" +#include "ns3/trace-source-accessor.h" +#include "ns3/object-vector.h" #include "ipv4-l3-protocol.h" #include "ipv4-l4-protocol.h" @@ -48,123 +50,34 @@ Ipv4L3Protocol::GetTypeId (void) { static TypeId tid = TypeId ("Ipv4L3Protocol") - .SetParent (); + .SetParent () + .AddConstructor () + .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.", + Uinteger (64), + MakeUintegerAccessor (&Ipv4L3Protocol::m_defaultTtl), + MakeUintegerChecker ()) + .AddAttribute ("Node", "The node to which this l3 protocol is attached.", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&Ipv4L3Protocol::m_node), + MakePtrChecker ()) + .AddTraceSource ("Tx", "Send ipv4 packet to outgoing interface.", + MakeTraceSourceAccessor (&Ipv4L3Protocol::m_txTrace)) + .AddTraceSource ("Rx", "Receive ipv4 packet from incoming interface.", + MakeTraceSourceAccessor (&Ipv4L3Protocol::m_rxTrace)) + .AddTraceSource ("Drop", "Drop ipv4 packet", + MakeTraceSourceAccessor (&Ipv4L3Protocol::m_dropTrace)) + .AddAttribute ("Interfaces", "The set of Ipv4 interfaces associated to this Ipv4 stack.", + ObjectVector (), + MakeObjectVectorAccessor (&Ipv4L3Protocol::m_interfaces), + MakeObjectVectorChecker ()) + ; return tid; } -Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement () - : m_type (TX) -{ - NS_LOG_FUNCTION; -} - -Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement (enum Type type) - : m_type (type) -{ - NS_LOG_FUNCTION; -} - -bool -Ipv4L3ProtocolTraceContextElement::IsTx (void) const -{ - NS_LOG_FUNCTION; - return m_type == TX; -} - -bool -Ipv4L3ProtocolTraceContextElement::IsRx (void) const -{ - NS_LOG_FUNCTION; - return m_type == RX; -} - -bool -Ipv4L3ProtocolTraceContextElement::IsDrop (void) const -{ - NS_LOG_FUNCTION; - return m_type == DROP; -} - -void -Ipv4L3ProtocolTraceContextElement::Print (std::ostream &os) const -{ - NS_LOG_FUNCTION; - os << "ipv4="; - switch (m_type) - { - case TX: - os << "tx"; - break; - case RX: - os << "rx"; - break; - case DROP: - os << "drop"; - break; - } -} - -uint16_t -Ipv4L3ProtocolTraceContextElement::GetUid (void) -{ - NS_LOG_FUNCTION; - static uint16_t uid = AllocateUid ("Ipv4L3ProtocolTraceContextElement"); - return uid; -} - -std::string -Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const -{ - NS_LOG_FUNCTION; - return "ns3::Ipv4L3ProtocolTraceContextElement"; -} - -Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex () - : m_index (0) -{ - NS_LOG_FUNCTION; -} - -Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index) - : m_index (index) -{ - NS_LOG_FUNCTION; -} - -uint32_t -Ipv4L3ProtocolInterfaceIndex::Get (void) const -{ - NS_LOG_FUNCTION; - return m_index; -} - -void -Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const -{ - os << "ipv4-interface=" << m_index; -} - -uint16_t -Ipv4L3ProtocolInterfaceIndex::GetUid (void) -{ - NS_LOG_FUNCTION; - static uint16_t uid = AllocateUid ("Ipv4L3ProtocolInterfaceIndex"); - return uid; -} - -std::string -Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const -{ - NS_LOG_FUNCTION; - return "ns3::Ipv4L3ProtocolInterfaceIndex"; -} - - -Ipv4L3Protocol::Ipv4L3Protocol(Ptr node) +Ipv4L3Protocol::Ipv4L3Protocol() : m_nInterfaces (0), - m_defaultTtl (64), - m_identification (0), - m_node (node) + m_identification (0) { NS_LOG_FUNCTION; m_staticRouting = CreateObject (); @@ -201,32 +114,6 @@ interface->SetUp (); } -Ptr -Ipv4L3Protocol::GetTraceResolver (void) const -{ - NS_LOG_FUNCTION; - - Ptr resolver = Create (); - resolver->AddSource ("tx", - TraceDoc ("send ipv4 packet to outgoing interface", - "Ptr", "packet sent", - "uint32_t", "index of output ipv4 interface"), - m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX)); - resolver->AddSource ("rx", - TraceDoc ("receive ipv4 packet from incoming interface", - "Ptr", "packet received", - "uint32_t", "index of input ipv4 interface"), - m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX)); - resolver->AddSource ("drop", - TraceDoc ("drop ipv4 packet", - "Ptr", "packet dropped"), - m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP)); - resolver->AddArray ("interfaces", - m_interfaces.begin (), m_interfaces.end (), - Ipv4L3ProtocolInterfaceIndex ()); - return resolver; -} - void Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) { diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l3-protocol.h --- a/src/internet-node/ipv4-l3-protocol.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l3-protocol.h Wed Feb 27 22:19:39 2008 +0100 @@ -24,11 +24,10 @@ #include #include -#include "ns3/callback-trace-source.h" -#include "ns3/trace-context-element.h" #include "ns3/ipv4-address.h" #include "ns3/ptr.h" #include "ns3/ipv4.h" +#include "ns3/traced-callback.h" #include "ipv4-header.h" #include "ipv4-static-routing.h" @@ -41,59 +40,6 @@ class Ipv4Header; class Ipv4Route; class Node; -class TraceResolver; -class TraceContext; - -/** - * \brief hold in a TraceContext the type of trace source used by this Ipv4L3Protocol - */ -class Ipv4L3ProtocolTraceContextElement : public TraceContextElement -{ -public: - enum Type { - TX, - RX, - DROP, - }; - Ipv4L3ProtocolTraceContextElement (); - Ipv4L3ProtocolTraceContextElement (enum Type type); - /** - * \returns true if this is a tx event, false otherwise. - */ - bool IsTx (void) const; - /** - * \returns true if this is a rx event, false otherwise. - */ - bool IsRx (void) const; - /** - * \returns true if this is a drop event, false otherwise. - */ - bool IsDrop (void) const; - void Print (std::ostream &os) const; - static uint16_t GetUid (void); - std::string GetTypeName (void) const; -private: - enum Type m_type; -}; - -/** - * \brief hold in a TraceContext the index of an Ipv4Interface within the ipv4 stack of a Node - */ -class Ipv4L3ProtocolInterfaceIndex : public TraceContextElement -{ -public: - Ipv4L3ProtocolInterfaceIndex (); - Ipv4L3ProtocolInterfaceIndex (uint32_t index); - /** - * \returns the index of the Ipv4Interface within a Node. - */ - uint32_t Get (void) const; - void Print (std::ostream &os) const; - static uint16_t GetUid (void); - std::string GetTypeName (void) const; -private: - uint32_t m_index; -}; class Ipv4L3Protocol : public Object @@ -102,7 +48,7 @@ static TypeId GetTypeId (void); static const uint16_t PROT_NUMBER; - Ipv4L3Protocol(Ptr node); + Ipv4L3Protocol(); virtual ~Ipv4L3Protocol (); /** @@ -213,7 +159,6 @@ protected: virtual void DoDispose (void); - virtual Ptr GetTraceResolver (void) const; private: void Lookup (uint32_t ifIndex, @@ -243,9 +188,9 @@ uint8_t m_defaultTtl; uint16_t m_identification; Ptr m_node; - CallbackTraceSource, uint32_t> m_txTrace; - CallbackTraceSource, uint32_t> m_rxTrace; - CallbackTraceSource > m_dropTrace; + TracedCallback, uint32_t> m_txTrace; + TracedCallback, uint32_t> m_rxTrace; + TracedCallback > m_dropTrace; Ipv4RoutingProtocolList m_routingProtocols; diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l4-demux.cc --- a/src/internet-node/ipv4-l4-demux.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l4-demux.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,8 +23,8 @@ // George F. Riley, Georgia Tech, Fall 2006 #include -#include "ns3/composite-trace-resolver.h" #include "ns3/node.h" +#include "ns3/object-vector.h" #include "ipv4-l4-demux.h" #include "ipv4-l4-protocol.h" @@ -32,44 +32,24 @@ NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Demux); -Ipv4L4ProtocolTraceContextElement::Ipv4L4ProtocolTraceContextElement () - : m_protocolNumber (0) -{} -Ipv4L4ProtocolTraceContextElement::Ipv4L4ProtocolTraceContextElement (int protocolNumber) - : m_protocolNumber (protocolNumber) -{} -int -Ipv4L4ProtocolTraceContextElement::Get (void) const -{ - return m_protocolNumber; -} -void -Ipv4L4ProtocolTraceContextElement::Print (std::ostream &os) const -{ - os << "ipv4-protocol=0x" << std::hex << m_protocolNumber << std::dec; -} -uint16_t -Ipv4L4ProtocolTraceContextElement::GetUid (void) -{ - static uint16_t uid = AllocateUid ("Ipv4L4ProtocolTraceContextElement"); - return uid; -} -std::string -Ipv4L4ProtocolTraceContextElement::GetTypeName (void) const -{ - return "ns3::Ipv4L4ProtocolTraceContextElement"; -} - TypeId Ipv4L4Demux::GetTypeId (void) { static TypeId tid = TypeId ("Ipv4L4Demux") - .SetParent (); + .SetParent () + .AddAttribute ("Node", "The node to which this object is associated.", + Ptr (0), + MakePtrAccessor (&Ipv4L4Demux::m_node), + MakePtrChecker ()) + .AddAttribute ("Protocols", "The set of protocols registered with this demux.", + ObjectVector (), + MakeObjectVectorAccessor (&Ipv4L4Demux::m_protocols), + MakeObjectVectorChecker ()) + ; return tid; } -Ipv4L4Demux::Ipv4L4Demux (Ptr node) - : m_node (node) +Ipv4L4Demux::Ipv4L4Demux () {} Ipv4L4Demux::~Ipv4L4Demux() @@ -88,21 +68,6 @@ Object::DoDispose (); } -Ptr -Ipv4L4Demux::GetTraceResolver (void) const -{ - Ptr resolver = Create (); - for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i) - { - Ptr protocol = *i; - std::ostringstream oss; - oss << (unsigned int) (*i)->GetProtocolNumber (); - Ipv4L4ProtocolTraceContextElement protocolNumber = (*i)->GetProtocolNumber (); - resolver->AddComposite (oss.str (), protocol, protocolNumber); - } - resolver->SetParentResolver (Object::GetTraceResolver ()); - return resolver; -} void Ipv4L4Demux::Insert(Ptr protocol) { diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l4-demux.h --- a/src/internet-node/ipv4-l4-demux.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l4-demux.h Wed Feb 27 22:19:39 2008 +0100 @@ -28,42 +28,21 @@ #include #include "ns3/object.h" #include "ns3/ptr.h" -#include "ns3/trace-context-element.h" namespace ns3 { class Ipv4L4Protocol; class Node; -class TraceResolver; class TraceContext; /** - * \brief hold in a TraceContext the protocol number of a L4 Protocol - */ -class Ipv4L4ProtocolTraceContextElement : public TraceContextElement -{ -public: - Ipv4L4ProtocolTraceContextElement (); - Ipv4L4ProtocolTraceContextElement (int protocolNumber); - /** - * \returns the protocol number as registered in the Ipv4L4Demux. - */ - int Get (void) const; - void Print (std::ostream &os) const; - static uint16_t GetUid (void); - std::string GetTypeName (void) const; -private: - int m_protocolNumber; -}; - -/** * \brief L4 Ipv4 Demux */ class Ipv4L4Demux : public Object { public: static TypeId GetTypeId (void); - Ipv4L4Demux (Ptr node); + Ipv4L4Demux (); virtual ~Ipv4L4Demux(); /** @@ -95,7 +74,6 @@ */ void Remove (Ptr protocol); protected: - Ptr GetTraceResolver (void) const; virtual void DoDispose (void); private: typedef std::list > L4List_t; diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l4-protocol.cc --- a/src/internet-node/ipv4-l4-protocol.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l4-protocol.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,32 +23,30 @@ // George F. Riley, Georgia Tech, Spring 2007 #include "ipv4-l4-protocol.h" +#include "ns3/uinteger.h" namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Protocol); -Ipv4L4Protocol::Ipv4L4Protocol(int protocolNumber, int version) - : m_protocolNumber (protocolNumber), - m_version (version) -{} +TypeId +Ipv4L4Protocol::GetTypeId (void) +{ + static TypeId tid = TypeId ("Ipv4L4Protocol") + .SetParent () + .AddAttribute ("ProtocolNumber", "The Ipv4 protocol number.", + Uinteger (0), + MakeUintegerAccessor (&Ipv4L4Protocol::GetProtocolNumber), + MakeUintegerChecker ()) + .AddAttribute ("Version", "The version of the protocol.", + Uinteger (0), + MakeUintegerAccessor (&Ipv4L4Protocol::GetVersion), + MakeUintegerChecker ()) + ; + return tid; +} + Ipv4L4Protocol::~Ipv4L4Protocol () {} -int -Ipv4L4Protocol::GetProtocolNumber (void) const -{ - return m_protocolNumber; -} -int -Ipv4L4Protocol::GetVersion() const -{ - return m_version; -} - -void -Ipv4L4Protocol::DoDispose (void) -{ - Object::DoDispose (); -} - }//namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/ipv4-l4-protocol.h --- a/src/internet-node/ipv4-l4-protocol.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/ipv4-l4-protocol.h Wed Feb 27 22:19:39 2008 +0100 @@ -44,17 +44,18 @@ class Ipv4L4Protocol : public Object { public: - Ipv4L4Protocol(int protocolNumber, int version); + static TypeId GetTypeId (void); + virtual ~Ipv4L4Protocol (); /** * \returns the protocol number of this protocol. */ - int GetProtocolNumber (void) const; + virtual int GetProtocolNumber (void) const = 0; /** * \returns the version number of this protocol. */ - int GetVersion() const; + virtual int GetVersion (void) const = 0; /** * \param p packet to forward up @@ -69,11 +70,6 @@ Ipv4Address const &source, Ipv4Address const &destination, Ptr incomingInterface) = 0; -protected: - virtual void DoDispose (void); -private: - int m_protocolNumber; - int m_version; }; } // Namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/tcp-l4-protocol.cc --- a/src/internet-node/tcp-l4-protocol.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/tcp-l4-protocol.cc Wed Feb 27 22:19:39 2008 +0100 @@ -41,6 +41,8 @@ namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol); + //State Machine things -------------------------------------------------------- TcpStateMachine::TcpStateMachine() : aT (LAST_STATE, StateActionVec_t(LAST_EVENT)), @@ -309,20 +311,42 @@ /* see http://www.iana.org/assignments/protocol-numbers */ const uint8_t TcpL4Protocol::PROT_NUMBER = 6; -TcpL4Protocol::TcpL4Protocol (Ptr node) - : Ipv4L4Protocol (PROT_NUMBER, 2), - m_node (node), - m_endPoints (new Ipv4EndPointDemux ()) +TypeId +TcpL4Protocol::GetTypeId (void) +{ + static TypeId tid = TypeId ("TcpL4Protocol") + .SetParent () + .AddAttribute ("Node", "The node to which this protocol is associated", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&TcpL4Protocol::m_node), + MakePtrChecker ()) + ; + return tid; +} + +TcpL4Protocol::TcpL4Protocol () + : m_endPoints (new Ipv4EndPointDemux ()) { NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << node); NS_LOG_LOGIC("Made a TcpL4Protocol "< node); + TcpL4Protocol (); virtual ~TcpL4Protocol (); + virtual int GetProtocolNumber (void) const; + virtual int GetVersion (void) const; + /** * \return A smart Socket pointer to a TcpSocket, allocated by this instance * of the TCP protocol diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/udp-l4-protocol.cc --- a/src/internet-node/udp-l4-protocol.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/udp-l4-protocol.cc Wed Feb 27 22:19:39 2008 +0100 @@ -35,13 +35,28 @@ namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (UdpL4Protocol); + /* see http://www.iana.org/assignments/protocol-numbers */ const uint8_t UdpL4Protocol::PROT_NUMBER = 17; -UdpL4Protocol::UdpL4Protocol (Ptr node) - : Ipv4L4Protocol (PROT_NUMBER, 2), - m_node (node), - m_endPoints (new Ipv4EndPointDemux ()) +TypeId +UdpL4Protocol::GetTypeId (void) +{ + static TypeId tid = TypeId ("UdpL4Protocol") + .SetParent () + .AddConstructor () + .AddAttribute ("Node", "The node which contains this protocol.", + TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, + Ptr (0), + MakePtrAccessor (&UdpL4Protocol::m_node), + MakePtrChecker ()) + ; + return tid; +} + +UdpL4Protocol::UdpL4Protocol () + : m_endPoints (new Ipv4EndPointDemux ()) { NS_LOG_FUNCTION; } @@ -51,6 +66,18 @@ NS_LOG_FUNCTION; } +int +UdpL4Protocol::GetProtocolNumber (void) const +{ + return PROT_NUMBER; +} +int +UdpL4Protocol::GetVersion (void) const +{ + return 2; +} + + void UdpL4Protocol::DoDispose (void) { diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/udp-l4-protocol.h --- a/src/internet-node/udp-l4-protocol.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/udp-l4-protocol.h Wed Feb 27 22:19:39 2008 +0100 @@ -41,14 +41,18 @@ */ class UdpL4Protocol : public Ipv4L4Protocol { public: + static TypeId GetTypeId (void); static const uint8_t PROT_NUMBER; /** * \brief Constructor * \param node The node this protocol is associated with */ - UdpL4Protocol (Ptr node); + UdpL4Protocol (); virtual ~UdpL4Protocol (); + virtual int GetProtocolNumber (void) const; + virtual int GetVersion (void) const; + /** * \return A smart Socket pointer to a UdpSocket, allocated by this instance * of the UDP protocol diff -r d64b1561b1c2 -r e667dc0f350e src/internet-node/udp-socket.cc --- a/src/internet-node/udp-socket.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/internet-node/udp-socket.cc Wed Feb 27 22:19:39 2008 +0100 @@ -400,7 +400,8 @@ Ptr rxNode = CreateObject (); Ptr rxDev1, rxDev2; { // first interface - rxDev1 = CreateObject (rxNode); + rxDev1 = CreateObjectWith ("Node", rxNode, "Address", Mac48Address::Allocate ()); + rxNode->AddDevice (rxDev1); rxDev1->AddQueue(CreateObject ()); Ptr ipv4 = rxNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (rxDev1); @@ -410,7 +411,8 @@ } { // second interface - rxDev2 = CreateObject (rxNode); + rxDev2 = CreateObjectWith ("Node", rxNode, "Address", Mac48Address::Allocate ()); + rxNode->AddDevice (rxDev2); rxDev2->AddQueue(CreateObject ()); Ptr ipv4 = rxNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (rxDev2); @@ -423,7 +425,7 @@ Ptr txNode = CreateObject (); Ptr txDev; { - txDev = CreateObject (txNode); + txDev = CreateObjectWith ("Node", txNode, "Address", Mac48Address::Allocate ()); txDev->AddQueue(CreateObject ()); Ptr ipv4 = txNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (txDev); diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/hierarchical-mobility-model.cc --- a/src/mobility/hierarchical-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/hierarchical-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -28,32 +28,52 @@ HierarchicalMobilityModel::GetTypeId (void) { static TypeId tid = TypeId ("HierarchicalMobilityModel") - .SetParent (); + .SetParent () + .AddConstructor () + .AddAttribute ("child", "The child mobility model.", + Ptr (0), + MakePtrAccessor (&HierarchicalMobilityModel::SetChild), + MakePtrChecker ()) + .AddAttribute ("parent", "The parent mobility model.", + Ptr (0), + MakePtrAccessor (&HierarchicalMobilityModel::SetParent), + MakePtrChecker ()) + ; return tid; } -HierarchicalMobilityModel::HierarchicalMobilityModel (Ptr child, Ptr parent) - : m_child (child), - m_parent (parent) +HierarchicalMobilityModel::HierarchicalMobilityModel () +{} + +void +HierarchicalMobilityModel::SetChild (Ptr model) { - Ptr childNotifier = + m_child = model; + Ptr notifier = m_child->GetObject (); - Ptr parentNotifier = - m_parent->GetObject (); - if (childNotifier == 0) + if (notifier == 0) { - childNotifier = CreateObject (); - child->AggregateObject (childNotifier); + notifier = CreateObject (); + m_child->AggregateObject (notifier); } - if (parentNotifier == 0) + notifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this)); +} + +void +HierarchicalMobilityModel::SetParent (Ptr model) +{ + m_parent = model; + Ptr notifier = + m_parent->GetObject (); + if (notifier == 0) { - parentNotifier = CreateObject (); - parent->AggregateObject (parentNotifier); + notifier = CreateObject (); + m_parent->AggregateObject (notifier); } - childNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ChildChanged, this)); - parentNotifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this)); + notifier->TraceConnect ("/course-changed", MakeCallback (&HierarchicalMobilityModel::ParentChanged, this)); } + Ptr HierarchicalMobilityModel::GetChild (void) const { diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/hierarchical-mobility-model.h --- a/src/mobility/hierarchical-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/hierarchical-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -35,11 +35,7 @@ public: static TypeId GetTypeId (void); - /** - * \param child the "relative" mobility model - * \param parent the "reference" mobility model - */ - HierarchicalMobilityModel (Ptr child, Ptr parent); + HierarchicalMobilityModel (); /** * \returns the child mobility model. @@ -62,6 +58,8 @@ virtual void DoSetPosition (const Vector &position); virtual Vector DoGetVelocity (void) const; + void SetChild (Ptr model); + void SetParent (Ptr model); void ParentChanged (const TraceContext &context, Ptr model); void ChildChanged (const TraceContext &context, Ptr model); diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/mobility-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/mobility-helper.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,139 @@ +#include "mobility-helper.h" +#include "mobility-model.h" +#include "mobility-model-notifier.h" +#include "position-allocator.h" +#include "hierarchical-mobility-model.h" + +namespace ns3 { + +MobilityHelper::MobilityHelper () + : m_notifierEnabled (false) +{} +void +MobilityHelper::EnableNotifier (void) +{ + m_notifierEnabled = true; +} +void +MobilityHelper::DisableNotifier (void) +{ + m_notifierEnabled = false; +} +void +MobilityHelper::SetPositionAllocator (Ptr allocator) +{ + m_position = allocator; +} +void +MobilityHelper::SetPositionAllocator (std::string type, + std::string n1, Attribute v1, + std::string n2, Attribute v2, + std::string n3, Attribute v3, + std::string n4, Attribute v4, + std::string n5, Attribute v5, + std::string n6, Attribute v6, + std::string n7, Attribute v7, + std::string n8, Attribute v8, + std::string n9, Attribute v9) +{ + ObjectFactory pos; + pos.SetTypeId (type); + pos.Set (n1, v1); + pos.Set (n2, v2); + pos.Set (n3, v3); + pos.Set (n4, v4); + pos.Set (n5, v5); + pos.Set (n6, v6); + pos.Set (n7, v7); + pos.Set (n8, v8); + pos.Set (n9, v9); + m_position = pos.Create ()->GetObject (); +} + +void +MobilityHelper::SetMobilityModel (std::string type, + std::string n1, Attribute v1, + std::string n2, Attribute v2, + std::string n3, Attribute v3, + std::string n4, Attribute v4, + std::string n5, Attribute v5, + std::string n6, Attribute v6, + std::string n7, Attribute v7, + std::string n8, Attribute v8, + std::string n9, Attribute v9) +{ + m_mobility.SetTypeId (type); + m_mobility.Set (n1, v1); + m_mobility.Set (n2, v2); + m_mobility.Set (n3, v3); + m_mobility.Set (n4, v4); + m_mobility.Set (n5, v5); + m_mobility.Set (n6, v6); + m_mobility.Set (n7, v7); + m_mobility.Set (n8, v8); + m_mobility.Set (n9, v9); +} + +void +MobilityHelper::PushReferenceMobilityModel (Ptr reference) +{ + Ptr mobility = reference->GetObject (); + m_mobilityStack.push_back (mobility); +} +void +MobilityHelper::PopReferenceMobilityModel (void) +{ + m_mobilityStack.pop_back (); +} + + +std::string +MobilityHelper::GetMobilityModelType (void) const +{ + return m_mobility.GetTypeId ().GetName (); +} + +void +MobilityHelper::Layout (const std::vector > &objects) +{ + for (std::vector >::const_iterator i = objects.begin (); i != objects.end (); i++) + { + Ptr object = *i; + Ptr model = object->GetObject (); + if (model == 0) + { + model = m_mobility.Create ()->GetObject (); + if (model == 0) + { + NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< + m_mobility.GetTypeId ().GetName ()<<"\""); + } + if (m_mobilityStack.empty ()) + { + object->AggregateObject (model); + } + else + { + // we need to setup a hierarchical mobility model + Ptr parent = m_mobilityStack.back (); + Ptr hierarchical = + CreateObjectWith ("child", model, + "parent", parent); + object->AggregateObject (hierarchical); + } + } + Vector position = m_position->GetNext (); + model->SetPosition (position); + if (m_notifierEnabled) + { + Ptr notifier = + object->GetObject (); + if (notifier == 0) + { + object->AggregateObject (CreateObject ()); + } + } + } +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/mobility-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/mobility-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,81 @@ +#ifndef MOBILITY_HELPER_H +#define MOBILITY_HELPER_H + +#include +#include "ns3/object-factory.h" +#include "ns3/attribute.h" +#include "position-allocator.h" + +namespace ns3 { + +class PositionAllocator; +class MobilityModel; + +class MobilityHelper +{ +public: + MobilityHelper (); + + void EnableNotifier (void); + void DisableNotifier (void); + + void SetPositionAllocator (Ptr allocator); + + void SetPositionAllocator (std::string type, + std::string n1 = "", Attribute v1 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute (), + std::string n5 = "", Attribute v5 = Attribute (), + std::string n6 = "", Attribute v6 = Attribute (), + std::string n7 = "", Attribute v7 = Attribute (), + std::string n8 = "", Attribute v8 = Attribute (), + std::string n9 = "", Attribute v9 = Attribute ()); + + void SetMobilityModel (std::string type, + std::string n1 = "", Attribute v1 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute (), + std::string n5 = "", Attribute v5 = Attribute (), + std::string n6 = "", Attribute v6 = Attribute (), + std::string n7 = "", Attribute v7 = Attribute (), + std::string n8 = "", Attribute v8 = Attribute (), + std::string n9 = "", Attribute v9 = Attribute ()); + + void PushReferenceMobilityModel (Ptr reference); + void PopReferenceMobilityModel (void); + + std::string GetMobilityModelType (void) const; + + template + void Layout (T begin, T end); +private: + void Layout (const std::vector > &objects); + + std::vector > m_mobilityStack; + bool m_notifierEnabled; + ObjectFactory m_mobility; + Ptr m_position; +}; + +} // namespace ns3 + +namespace ns3 { + +template +void +MobilityHelper::Layout (T begin, T end) +{ + std::vector > objects; + for (T i = begin; i != end; i++) + { + Ptr object = *i; + objects.push_back (object); + } + Layout (objects); +} + +} // namespace ns3 + +#endif /* MOBILITY_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/mobility-model.cc --- a/src/mobility/mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -27,7 +27,19 @@ MobilityModel::GetTypeId (void) { static TypeId tid = TypeId ("MobilityModel") - .SetParent (); + .SetParent () + .AddAttribute ("position", "The current position of the mobility model.", + TypeId::ATTR_SGC, + Vector (0.0, 0.0, 0.0), + MakeVectorAccessor (&MobilityModel::SetPosition, + &MobilityModel::GetPosition), + MakeVectorChecker ()) + .AddAttribute ("velocity", "The current velocity of the mobility model.", + TypeId::ATTR_GET, + Vector (0.0, 0.0, 0.0), // ignored initial value. + MakeVectorAccessor (&MobilityModel::GetVelocity), + MakeVectorChecker ()) + ; return tid; } diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/ns2-mobility-file-topology.cc --- a/src/mobility/ns2-mobility-file-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INRIA - * All rights reserved. - * - * 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: Mathieu Lacage - */ -#include -#include -#include "ns3/log.h" -#include "ns3/simulator.h" -#include "ns3/node-list.h" -#include "ns3/node.h" -#include "ns2-mobility-file-topology.h" -#include "static-speed-mobility-model.h" - -NS_LOG_COMPONENT_DEFINE ("Ns2MobilityFileTopology"); - -namespace ns3 { - - -Ns2MobilityFileTopology::Ns2MobilityFileTopology (std::string filename) - : m_filename (filename) -{} - - -Ptr -Ns2MobilityFileTopology::GetMobilityModel (std::string idString, const ObjectStore &store) const -{ - std::istringstream iss; - iss.str (idString); - uint32_t id; - iss >> id; - Ptr object = store.Get (id); - if (object == 0) - { - return 0; - } - Ptr model = object->GetObject (); - if (model == 0) - { - model = CreateObject (); - object->AggregateObject (model); - } - return model; -} - -double -Ns2MobilityFileTopology::ReadDouble (std::string valueString) const -{ - std::istringstream iss; - iss.str (valueString); - double value; - iss >> value; - return value; -} - -void -Ns2MobilityFileTopology::LayoutObjectStore (const ObjectStore &store) const -{ - std::ifstream file (m_filename.c_str (), std::ios::in); - if (file.is_open()) - { - while (!file.eof() ) - { - std::string line; - getline (file, line); - std::string::size_type startNodeId = line.find_first_of ("("); - std::string::size_type endNodeId = line.find_first_of (")"); - if (startNodeId == std::string::npos || - endNodeId == std::string::npos) - { - continue; - } - Ptr model = GetMobilityModel (line.substr (startNodeId + 1, - endNodeId - startNodeId), - store); - if (model == 0) - { - continue; - } - if (startNodeId == 6) - { - double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos)); - std::string coordinate = line.substr (endNodeId + 6, 1); - Vector position = model->GetPosition (); - if (coordinate == "X") - { - position.x = value; - NS_LOG_DEBUG ("X=" << value); - } - else if (coordinate == "Y") - { - position.y = value; - NS_LOG_DEBUG ("Y=" << value); - } - else if (coordinate == "Z") - { - position.z = value; - NS_LOG_DEBUG ("Z=" << value); - } - else - { - continue; - } - model->SetPosition (position); - } - else - { - double at = ReadDouble (line.substr (8, startNodeId - 17)); - std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10); - std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1); - double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10)); - double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1)); - double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos)); - NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed); - Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetSpeed, model, - Vector (xSpeed, ySpeed, zSpeed)); - } - } - file.close(); - } -} - -void -Ns2MobilityFileTopology::Layout (void) const -{ - Layout (NodeList::Begin (), NodeList::End ()); -} - -} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/ns2-mobility-file-topology.h --- a/src/mobility/ns2-mobility-file-topology.h Tue Feb 26 01:39:59 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INRIA - * All rights reserved. - * - * 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: Mathieu Lacage - */ -#ifndef NS2_MOBILITY_FILE_TOPOLOGY_H -#define NS2_MOBILITY_FILE_TOPOLOGY_H - -#include -#include -#include "ns3/ptr.h" -#include "ns3/object.h" -#include "static-speed-mobility-model.h" - -namespace ns3 { - -/** - * \brief a topology object which can read ns2's movement files - * generated by the CMU setdest tool. - */ -class Ns2MobilityFileTopology -{ -public: - /** - * \param filename filename of file which contains the - * ns2 movement trace. - */ - Ns2MobilityFileTopology (std::string filename); - - /** - * Read the ns2 trace file and configure the movement - * patterns of all nodes contained in the global ns3::NodeList - * whose nodeId is matches the nodeId of the nodes in the trace - * file. - */ - void Layout (void) const; - - /** - * \param begin an iterator which points to the start of the input - * object array. - * \param end an iterator which points to the end of the input - * object array. - * - * Read the ns2 trace file and configure the movement - * patterns of all input objects. Each input object - * is identified by a unique node id which reflects - * the index of the object in the input array. - */ - template - void Layout (T begin, T end) const; -private: - class ObjectStore - { - public: - virtual ~ObjectStore () {} - virtual Ptr Get (uint32_t i) const = 0; - }; - void LayoutObjectStore (const ObjectStore &store) const; - Ptr GetMobilityModel (std::string idString, const ObjectStore &store) const; - double ReadDouble (std::string valueString) const; - std::string m_filename; -}; - -} // namespace ns3 - -namespace ns3 { - -template -void -Ns2MobilityFileTopology::Layout (T begin, T end) const -{ - class MyObjectStore : public ObjectStore - { - public: - MyObjectStore (T begin, T end) - : m_begin (begin), - m_end (end) - {} - virtual Ptr Get (uint32_t i) const { - T iterator = m_begin; - iterator += i; - if (iterator >= m_end) - { - return 0; - } - return *iterator; - } - private: - T m_begin; - T m_end; - }; - LayoutObjectStore (MyObjectStore (begin, end)); -} - - -} // namespace ns3 - -#endif /* NS2_MOBILITY_FILE_TOPOLOGY_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/ns2-mobility-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/ns2-mobility-helper.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,163 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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: Mathieu Lacage + */ +#include +#include +#include "ns3/log.h" +#include "ns3/simulator.h" +#include "ns3/node-list.h" +#include "ns3/node.h" +#include "ns2-mobility-helper.h" +#include "static-speed-mobility-model.h" +#include "mobility-model-notifier.h" + +NS_LOG_COMPONENT_DEFINE ("Ns2MobilityHelper"); + +namespace ns3 { + + +Ns2MobilityHelper::Ns2MobilityHelper (std::string filename) + : m_filename (filename) +{} + +void +Ns2MobilityHelper::EnableNotifier (void) +{ + m_notifierEnabled = true; +} +void +Ns2MobilityHelper::DisableNotifier (void) +{ + m_notifierEnabled = false; +} + + + +Ptr +Ns2MobilityHelper::GetMobilityModel (std::string idString, const ObjectStore &store) const +{ + std::istringstream iss; + iss.str (idString); + uint32_t id; + iss >> id; + Ptr object = store.Get (id); + if (object == 0) + { + return 0; + } + Ptr model = object->GetObject (); + if (model == 0) + { + model = CreateObject (); + object->AggregateObject (model); + } + Ptr notifier = object->GetObject (); + if (notifier == 0) + { + notifier = CreateObject (); + object->AggregateObject (notifier); + } + return model; +} + +double +Ns2MobilityHelper::ReadDouble (std::string valueString) const +{ + std::istringstream iss; + iss.str (valueString); + double value; + iss >> value; + return value; +} + +void +Ns2MobilityHelper::LayoutObjectStore (const ObjectStore &store) const +{ + std::ifstream file (m_filename.c_str (), std::ios::in); + if (file.is_open()) + { + while (!file.eof() ) + { + std::string line; + getline (file, line); + std::string::size_type startNodeId = line.find_first_of ("("); + std::string::size_type endNodeId = line.find_first_of (")"); + if (startNodeId == std::string::npos || + endNodeId == std::string::npos) + { + continue; + } + Ptr model = GetMobilityModel (line.substr (startNodeId + 1, + endNodeId - startNodeId), + store); + if (model == 0) + { + continue; + } + if (startNodeId == 6) + { + double value = ReadDouble (line.substr (endNodeId + 9, std::string::npos)); + std::string coordinate = line.substr (endNodeId + 6, 1); + Vector position = model->GetPosition (); + if (coordinate == "X") + { + position.x = value; + NS_LOG_DEBUG ("X=" << value); + } + else if (coordinate == "Y") + { + position.y = value; + NS_LOG_DEBUG ("Y=" << value); + } + else if (coordinate == "Z") + { + position.z = value; + NS_LOG_DEBUG ("Z=" << value); + } + else + { + continue; + } + model->SetPosition (position); + } + else + { + double at = ReadDouble (line.substr (8, startNodeId - 17)); + std::string::size_type xSpeedEnd = line.find_first_of (" ", endNodeId + 10); + std::string::size_type ySpeedEnd = line.find_first_of (" ", xSpeedEnd + 1); + double xSpeed = ReadDouble (line.substr (endNodeId + 10, xSpeedEnd - endNodeId - 10)); + double ySpeed = ReadDouble (line.substr (xSpeedEnd + 1, ySpeedEnd - xSpeedEnd - 1)); + double zSpeed = ReadDouble (line.substr (ySpeedEnd + 1, std::string::npos)); + NS_LOG_DEBUG ("at=" << at << "xSpeed=" << xSpeed << ", ySpeed=" << ySpeed << ", zSpeed=" << zSpeed); + Simulator::Schedule (Seconds (at), &StaticSpeedMobilityModel::SetSpeed, model, + Vector (xSpeed, ySpeed, zSpeed)); + } + } + file.close(); + } +} + +void +Ns2MobilityHelper::Layout (void) const +{ + Layout (NodeList::Begin (), NodeList::End ()); +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/ns2-mobility-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/ns2-mobility-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,117 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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: Mathieu Lacage + */ +#ifndef NS2_MOBILITY_FILE_TOPOLOGY_H +#define NS2_MOBILITY_FILE_TOPOLOGY_H + +#include +#include +#include "ns3/ptr.h" +#include "ns3/object.h" +#include "static-speed-mobility-model.h" + +namespace ns3 { + +/** + * \brief a topology object which can read ns2's movement files + * generated by the CMU setdest tool. + */ +class Ns2MobilityHelper +{ +public: + /** + * \param filename filename of file which contains the + * ns2 movement trace. + */ + Ns2MobilityHelper (std::string filename); + + void EnableNotifier (void); + void DisableNotifier (void); + + /** + * Read the ns2 trace file and configure the movement + * patterns of all nodes contained in the global ns3::NodeList + * whose nodeId is matches the nodeId of the nodes in the trace + * file. + */ + void Layout (void) const; + + /** + * \param begin an iterator which points to the start of the input + * object array. + * \param end an iterator which points to the end of the input + * object array. + * + * Read the ns2 trace file and configure the movement + * patterns of all input objects. Each input object + * is identified by a unique node id which reflects + * the index of the object in the input array. + */ + template + void Layout (T begin, T end) const; +private: + class ObjectStore + { + public: + virtual ~ObjectStore () {} + virtual Ptr Get (uint32_t i) const = 0; + }; + void LayoutObjectStore (const ObjectStore &store) const; + Ptr GetMobilityModel (std::string idString, const ObjectStore &store) const; + double ReadDouble (std::string valueString) const; + std::string m_filename; + bool m_notifierEnabled; +}; + +} // namespace ns3 + +namespace ns3 { + +template +void +Ns2MobilityHelper::Layout (T begin, T end) const +{ + class MyObjectStore : public ObjectStore + { + public: + MyObjectStore (T begin, T end) + : m_begin (begin), + m_end (end) + {} + virtual Ptr Get (uint32_t i) const { + T iterator = m_begin; + iterator += i; + if (iterator >= m_end) + { + return 0; + } + return *iterator; + } + private: + T m_begin; + T m_end; + }; + LayoutObjectStore (MyObjectStore (begin, end)); +} + + +} // namespace ns3 + +#endif /* NS2_MOBILITY_FILE_TOPOLOGY_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/position-allocator.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/position-allocator.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,190 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * + * 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: Mathieu Lacage + */ +#include "position-allocator.h" +#include "ns3/random-variable.h" +#include "ns3/double.h" +#include "ns3/integer.h" +#include "ns3/enum.h" +#include "ns3/log.h" +#include + +NS_LOG_COMPONENT_DEFINE ("PositionAllocator"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (PositionAllocator); + +TypeId +PositionAllocator::GetTypeId (void) +{ + static TypeId tid = TypeId ("PositionAllocator") + .SetParent (); + return tid; +} + +PositionAllocator::PositionAllocator () +{ +} + +PositionAllocator::~PositionAllocator () +{} + +TypeId +GridPositionAllocator::GetTypeId (void) +{ + static TypeId tid = TypeId ("GridPositionAllocator") + .SetParent () + .SetGroupName ("Mobility") + .AddConstructor () + .AddAttribute ("GridWidth", "The number of objects layed out on a line.", + Integer (10), + MakeIntegerAccessor (&GridPositionAllocator::m_n), + MakeIntegerChecker ()) + .AddAttribute ("MinX", "The x coordinate where the grid starts.", + Double (1.0), + MakeDoubleAccessor (&GridPositionAllocator::m_xMin), + MakeDoubleChecker ()) + .AddAttribute ("MinY", "The y coordinate where the grid starts.", + Double (0.0), + MakeDoubleAccessor (&GridPositionAllocator::m_yMin), + MakeDoubleChecker ()) + .AddAttribute ("DeltaX", "The x space between objects.", + Double (1.0), + MakeDoubleAccessor (&GridPositionAllocator::m_deltaX), + MakeDoubleChecker ()) + .AddAttribute ("DeltaY", "The y space between objects.", + Double (1.0), + MakeDoubleAccessor (&GridPositionAllocator::m_deltaY), + MakeDoubleChecker ()) + .AddAttribute ("LayoutType", "The type of layout.", + Enum (ROW_FIRST), + MakeEnumAccessor (&GridPositionAllocator::m_layoutType), + MakeEnumChecker (ROW_FIRST, "RowFirst", + COLUMN_FIRST, "ColumnFirst")) + ; + return tid; +} +GridPositionAllocator::GridPositionAllocator () + : m_current (0) +{} + +Vector +GridPositionAllocator::GetNext (void) const +{ + double x = 0.0, y = 0.0; + switch (m_layoutType) { + case ROW_FIRST: + x = m_xMin + m_deltaX * (m_current % m_n); + y = m_yMin + m_deltaY * (m_current / m_n); + break; + case COLUMN_FIRST: + x = m_xMin + m_deltaX * (m_current / m_n); + y = m_yMin + m_deltaY * (m_current % m_n); + break; + } + m_current++; + return Vector (x, y, 0.0); +} + + +NS_OBJECT_ENSURE_REGISTERED (RandomRectanglePositionAllocator); + +TypeId +RandomRectanglePositionAllocator::GetTypeId (void) +{ + static TypeId tid = TypeId ("RandomRectanglePositionAllocator") + .SetParent () + .SetGroupName ("Mobility") + .AddConstructor () + .AddAttribute ("X", + "A random variable which represents the x coordinate of a position in a random rectangle.", + UniformVariable (0.0, 1.0), + MakeRandomVariableAccessor (&RandomRectanglePositionAllocator::m_x), + MakeRandomVariableChecker ()) + .AddAttribute ("Y", + "A random variable which represents the y coordinate of a position in a random rectangle.", + UniformVariable (0.0, 1.0), + MakeRandomVariableAccessor (&RandomRectanglePositionAllocator::m_y), + MakeRandomVariableChecker ()); + return tid; +} + +RandomRectanglePositionAllocator::RandomRectanglePositionAllocator () +{} +RandomRectanglePositionAllocator::~RandomRectanglePositionAllocator () +{} +Vector +RandomRectanglePositionAllocator::GetNext (void) const +{ + double x = m_x.GetValue (); + double y = m_y.GetValue (); + return Vector (x, y, 0.0); +} + +NS_OBJECT_ENSURE_REGISTERED (RandomDiscPositionAllocator); + +TypeId +RandomDiscPositionAllocator::GetTypeId (void) +{ + static TypeId tid = TypeId ("RandomDiscPositionAllocator") + .SetParent () + .SetGroupName ("Mobility") + .AddConstructor () + .AddAttribute ("Theta", + "A random variable which represents the angle (gradients) of a position in a random disc.", + UniformVariable (0.0, 6.2830), + MakeRandomVariableAccessor (&RandomDiscPositionAllocator::m_theta), + MakeRandomVariableChecker ()) + .AddAttribute ("Rho", + "A random variable which represents the radius of a position in a random disc.", + UniformVariable (0.0, 200.0), + MakeRandomVariableAccessor (&RandomDiscPositionAllocator::m_rho), + MakeRandomVariableChecker ()) + .AddAttribute ("X", + "The x coordinate of the center of the random position disc.", + Double (0.0), + MakeDoubleAccessor (&RandomDiscPositionAllocator::m_x), + MakeDoubleChecker ()) + .AddAttribute ("Y", + "The y coordinate of the center of the random position disc.", + Double (0.0), + MakeDoubleAccessor (&RandomDiscPositionAllocator::m_y), + MakeDoubleChecker ()) + ; + return tid; +} + +RandomDiscPositionAllocator::RandomDiscPositionAllocator () +{} +RandomDiscPositionAllocator::~RandomDiscPositionAllocator () +{} +Vector +RandomDiscPositionAllocator::GetNext (void) const +{ + double theta = m_theta.GetValue (); + double rho = m_rho.GetValue (); + double x = m_x + std::cos (theta) * rho; + double y = m_y + std::sin (theta) * rho; + NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y); + return Vector (x, y, 0.0); +} + + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/position-allocator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/mobility/position-allocator.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,105 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * + * 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: Mathieu Lacage + */ +#ifndef POSITION_ALLOCATOR_H +#define POSITION_ALLOCATOR_H + +#include "ns3/object.h" +#include "ns3/random-variable.h" +#include "vector.h" + +namespace ns3 { + +/** + * \brief choose a position at random. + * + * This is a pure abstract base class. + */ +class PositionAllocator : public Object +{ +public: + static TypeId GetTypeId (void); + PositionAllocator (); + virtual ~PositionAllocator (); + /** + * \returns the next randomly-choosen position. + */ + virtual Vector GetNext (void) const = 0; +}; + +class GridPositionAllocator : public Object +{ +public: + static TypeId GetTypeId (void); + + enum LayoutType { + ROW_FIRST, + COLUMN_FIRST + }; + + GridPositionAllocator (); + + virtual Vector GetNext (void) const; +private: + mutable uint32_t m_current; + enum LayoutType m_layoutType; + double m_xMin; + double m_yMin; + uint32_t m_n; + double m_deltaX; + double m_deltaY; +}; + +/** + * \brief allocate random positions within a rectangle + * according to a pair of random variables. + */ +class RandomRectanglePositionAllocator : public PositionAllocator +{ +public: + static TypeId GetTypeId (void); + RandomRectanglePositionAllocator (); + virtual ~RandomRectanglePositionAllocator (); + virtual Vector GetNext (void) const; +private: + RandomVariable m_x; + RandomVariable m_y; +}; + +/** + * \brief allocate random positions within a disc + * according to a pair of random variables. + */ +class RandomDiscPositionAllocator : public PositionAllocator +{ +public: + static TypeId GetTypeId (void); + RandomDiscPositionAllocator (); + virtual ~RandomDiscPositionAllocator (); + virtual Vector GetNext (void) const; +private: + RandomVariable m_theta; + RandomVariable m_rho; + double m_x; + double m_y; +}; + +} // namespace ns3 + +#endif /* RANDOM_POSITION_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-direction-2d-mobility-model.cc --- a/src/mobility/random-direction-2d-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-direction-2d-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -19,7 +19,6 @@ * Author: Mathieu Lacage */ #include "ns3/random-variable-default-value.h" -#include "ns3/rectangle-default-value.h" #include "ns3/simulator.h" #include #include @@ -35,100 +34,37 @@ NS_OBJECT_ENSURE_REGISTERED (RandomDirection2dMobilityModel); -static RandomVariableDefaultValue - g_speedVariable ("RandomDirection2dSpeed", - "A random variable to control the speed of a RandomDirection2d mobility model.", - "Uniform:1:2"); - -static RandomVariableDefaultValue - g_pauseVariable ("RandomDirection2dPause", - "A random variable to control the duration " - "of the pause of a RandomDiretion mobility model.", - "Constant:2"); - -static RectangleDefaultValue - g_bounds ("RandomDirection2dArea", - "The bounding area for the RandomDirection2d model.", - -100, 100, -100, 100); - - -RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters () - : m_bounds (g_bounds.GetValue ()), - m_speedVariable (g_speedVariable.Get ()), - m_pauseVariable (g_pauseVariable.Get ()) - -{} -RandomDirection2dMobilityModelParameters::RandomDirection2dMobilityModelParameters -(const Rectangle &bounds, - const RandomVariable &speedVariable, - const RandomVariable &pauseVariable) - : m_bounds (bounds), - m_speedVariable (speedVariable), - m_pauseVariable (pauseVariable) -{} - -RandomDirection2dMobilityModelParameters::~RandomDirection2dMobilityModelParameters () -{} - -void -RandomDirection2dMobilityModelParameters::SetSpeed (const RandomVariable &speedVariable) -{ - m_speedVariable = speedVariable; -} -void -RandomDirection2dMobilityModelParameters::SetPause (const RandomVariable &pauseVariable) -{ - m_pauseVariable = pauseVariable; -} -void -RandomDirection2dMobilityModelParameters::SetBounds (const Rectangle &bounds) -{ - m_bounds = bounds; -} - -Ptr -RandomDirection2dMobilityModelParameters::GetCurrent (void) -{ - static Ptr parameters = 0; - if (parameters == 0 || - g_bounds.IsDirty () || - g_speedVariable.IsDirty () || - g_pauseVariable.IsDirty ()) - { - parameters = CreateObject (); - g_bounds.ClearDirtyFlag (); - g_speedVariable.ClearDirtyFlag (); - g_pauseVariable.ClearDirtyFlag (); - } - return parameters; -} - TypeId RandomDirection2dMobilityModel::GetTypeId (void) { static TypeId tid = TypeId ("RandomDirection2dMobilityModel") .SetParent () + .SetGroupName ("Mobility") .AddConstructor () - .AddConstructor > (); + .AddAttribute ("bounds", "The 2d bounding area", + Rectangle (-100, 100, -100, 100), + MakeRectangleAccessor (&RandomDirection2dMobilityModel::m_bounds), + MakeRectangleChecker ()) + .AddAttribute ("speed", "A random variable to control the speed (m/s).", + UniformVariable (1.0, 2.0), + MakeRandomVariableAccessor (&RandomDirection2dMobilityModel::m_speed), + MakeRandomVariableChecker ()) + .AddAttribute ("pause", "A random variable to control the pause (s).", + ConstantVariable (2.0), + MakeRandomVariableAccessor (&RandomDirection2dMobilityModel::m_pause), + MakeRandomVariableChecker ()) + ; return tid; } RandomDirection2dMobilityModel::RandomDirection2dMobilityModel () - : m_parameters (RandomDirection2dMobilityModelParameters::GetCurrent ()) -{ - m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this); -} -RandomDirection2dMobilityModel::RandomDirection2dMobilityModel -(Ptr parameters) - : m_parameters (parameters) { m_event = Simulator::ScheduleNow (&RandomDirection2dMobilityModel::Start, this); } void RandomDirection2dMobilityModel::DoDispose (void) { - m_parameters = 0; // chain up. MobilityModel::DoDispose (); } @@ -142,7 +78,7 @@ void RandomDirection2dMobilityModel::BeginPause (void) { - Time pause = Seconds (m_parameters->m_pauseVariable.GetValue ()); + Time pause = Seconds (m_pause.GetValue ()); m_helper.Pause (); m_event = Simulator::Schedule (pause, &RandomDirection2dMobilityModel::ResetDirectionAndSpeed, this); NotifyCourseChange (); @@ -152,13 +88,13 @@ RandomDirection2dMobilityModel::SetDirectionAndSpeed (double direction) { NS_LOG_FUNCTION; - double speed = m_parameters->m_speedVariable.GetValue (); + double speed = m_speed.GetValue (); const Vector vector (std::cos (direction) * speed, std::sin (direction) * speed, 0.0); - Vector position = m_helper.GetCurrentPosition (m_parameters->m_bounds); + Vector position = m_helper.GetCurrentPosition (m_bounds); m_helper.Reset (vector); - Vector next = m_parameters->m_bounds.CalculateIntersection (position, vector); + Vector next = m_bounds.CalculateIntersection (position, vector); Time delay = Seconds (CalculateDistance (position, next) / speed); m_event = Simulator::Schedule (delay, &RandomDirection2dMobilityModel::BeginPause, this); @@ -169,8 +105,8 @@ { double direction = UniformVariable::GetSingleValue (0, PI); - Vector position = m_helper.GetCurrentPosition (m_parameters->m_bounds); - switch (m_parameters->m_bounds.GetClosestSide (position)) + Vector position = m_helper.GetCurrentPosition (m_bounds); + switch (m_bounds.GetClosestSide (position)) { case Rectangle::RIGHT: direction += PI / 2; @@ -190,7 +126,7 @@ Vector RandomDirection2dMobilityModel::DoGetPosition (void) const { - return m_helper.GetCurrentPosition (m_parameters->m_bounds); + return m_helper.GetCurrentPosition (m_bounds); } void RandomDirection2dMobilityModel::DoSetPosition (const Vector &position) diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-direction-2d-mobility-model.h --- a/src/mobility/random-direction-2d-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-direction-2d-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -33,50 +33,6 @@ namespace ns3 { /** - * \brief the parameters to control a RandomDirection mobility model. - */ -class RandomDirection2dMobilityModelParameters : public Object -{ - public: - /** - * Create from \valueref{RandomDirection2dSpeed}, - * \valueref{RandomDirection2dPause}, and, - * \valueref{RandomDirection2dArea}. - */ - RandomDirection2dMobilityModelParameters (); - /** - * \param bounds the 2d bounds of the mobility model - * \param speedVariable the random variable used to pick a random speed - * \param pauseVariable the random variable used to pick a random pause delay - */ - RandomDirection2dMobilityModelParameters (const Rectangle &bounds, - const RandomVariable &speedVariable, - const RandomVariable &pauseVariable); - virtual ~RandomDirection2dMobilityModelParameters (); - - /** - * \param speedVariable the random variable used to pick a random speed. - */ - void SetSpeed (const RandomVariable &speedVariable); - /** - * \param pauseVariable the random variable used to pick a random pause delay. - */ - void SetPause (const RandomVariable &pauseVariable); - /** - * \param bounds the 2d bounds of the mobility model. - */ - void SetBounds (const Rectangle &bounds); - private: - friend class RandomDirection2dMobilityModel; - - static Ptr GetCurrent (void); - - Rectangle m_bounds; - RandomVariable m_speedVariable; - RandomVariable m_pauseVariable; -}; - -/** * \brief a RandomDirection mobility model * * The movement of objects is based on random directions: each object @@ -96,11 +52,6 @@ * \valueref{RandomDirection2dArea}. */ RandomDirection2dMobilityModel (); - /** - * \param parameters the parameters which control the behavior of the model. - * Create a RandomDirection model using the parameters specified. - */ - RandomDirection2dMobilityModel (Ptr parameters); private: void Start (void); void ResetDirectionAndSpeed (void); @@ -113,7 +64,9 @@ virtual Vector DoGetVelocity (void) const; static const double PI; - Ptr m_parameters; + Rectangle m_bounds; + RandomVariable m_speed; + RandomVariable m_pause; EventId m_event; StaticSpeedHelper m_helper; }; diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-position.cc --- a/src/mobility/random-position.cc Tue Feb 26 01:39:59 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INRIA - * - * 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: Mathieu Lacage - */ -#include "random-position.h" -#include "ns3/random-variable.h" -#include "ns3/default-value.h" -#include "ns3/random-variable-default-value.h" -#include "ns3/log.h" -#include - -NS_LOG_COMPONENT_DEFINE ("RandomPosition"); - -namespace ns3 { - -static RandomVariableDefaultValue -g_rectangleX ("RandomRectanglePositionX", - "A random variable which represents the x position of a position in a random rectangle.", - "Uniform:0:200"); - -static RandomVariableDefaultValue -g_rectangleY ("RandomRectanglePositionY", - "A random variable which represents the y position of a position in a random rectangle.", - "Uniform:0:200"); - -static RandomVariableDefaultValue -g_discTheta ("RandomDiscPositionTheta", - "A random variable which represents the angle (gradients) of a position in a random disc.", - "Uniform:0:6.2830"); - -static RandomVariableDefaultValue -g_discRho ("RandomDiscPositionRho", - "A random variable which represents the radius of a position in a random disc.", - "Uniform:0:200"); - -static NumericDefaultValue -g_discX ("RandomDiscPositionX", - "The x coordinate of the center of the random position disc.", - 0.0); - -static NumericDefaultValue -g_discY ("RandomDiscPositionY", - "The y coordinate of the center of the random position disc.", - 0.0); - -NS_OBJECT_ENSURE_REGISTERED (RandomPosition); - -TypeId -RandomPosition::GetTypeId (void) -{ - static TypeId tid = TypeId ("RandomPosition") - .SetParent (); - return tid; -} - -RandomPosition::RandomPosition () -{ -} - -RandomPosition::~RandomPosition () -{} - -NS_OBJECT_ENSURE_REGISTERED (RandomRectanglePosition); - -TypeId -RandomRectanglePosition::GetTypeId (void) -{ - static TypeId tid = TypeId ("RandomRectanglePosition") - .SetParent () - .AddConstructor () - .AddConstructor (); - return tid; -} - -RandomRectanglePosition::RandomRectanglePosition () - : m_x (g_rectangleX.Get ()), - m_y (g_rectangleY.Get ()) -{} -RandomRectanglePosition::RandomRectanglePosition (const RandomVariable &x, - const RandomVariable &y) - : m_x (x), - m_y (y) -{} -RandomRectanglePosition::~RandomRectanglePosition () -{} -Vector -RandomRectanglePosition::Get (void) const -{ - double x = m_x.GetValue (); - double y = m_y.GetValue (); - return Vector (x, y, 0.0); -} - -NS_OBJECT_ENSURE_REGISTERED (RandomDiscPosition); - -TypeId -RandomDiscPosition::GetTypeId (void) -{ - static TypeId tid = TypeId ("RandomDiscPosition") - .SetParent () - .AddConstructor () - .AddConstructor (); - return tid; -} - -RandomDiscPosition::RandomDiscPosition () - : m_theta (g_discTheta.Get ()), - m_rho (g_discRho.Get ()), - m_x (g_discX.GetValue ()), - m_y (g_discY.GetValue ()) -{} -RandomDiscPosition::RandomDiscPosition (const RandomVariable &theta, - const RandomVariable &rho, - double x, double y) - : m_theta (theta), - m_rho (rho), - m_x (0.0), - m_y (0.0) -{} -RandomDiscPosition::~RandomDiscPosition () -{} -Vector -RandomDiscPosition::Get (void) const -{ - double theta = m_theta.GetValue (); - double rho = m_rho.GetValue (); - double x = m_x + std::cos (theta) * rho; - double y = m_y + std::sin (theta) * rho; - NS_LOG_DEBUG ("Disc position x=" << x << ", y=" << y); - return Vector (x, y, 0.0); -} - - -} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-position.h --- a/src/mobility/random-position.h Tue Feb 26 01:39:59 2008 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2007 INRIA - * - * 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: Mathieu Lacage - */ -#ifndef RANDOM_POSITION_H -#define RANDOM_POSITION_H - -#include "ns3/object.h" -#include "ns3/random-variable.h" -#include "vector.h" - -namespace ns3 { - -/** - * \brief choose a position at random. - * - * This is a pure abstract base class. - */ -class RandomPosition : public Object -{ -public: - static TypeId GetTypeId (void); - RandomPosition (); - virtual ~RandomPosition (); - /** - * \returns the next randomly-choosen position. - */ - virtual Vector Get (void) const = 0; -}; - -/** - * \brief allocate random positions within a rectangle - * according to a pair of random variables. - */ -class RandomRectanglePosition : public RandomPosition -{ -public: - static TypeId GetTypeId (void); - /** - * Create a random position model with construction - * values from \valueref{RandomRectanglePositionX}, and - * \valueref{RandomRectanglePositionY} - */ - RandomRectanglePosition (); - /** - * \param x the random variable which is used to choose - * the x coordinates. - * \param y the random variable which is used to choose - * the y coordinates. - */ - RandomRectanglePosition (const RandomVariable &x, - const RandomVariable &y); - virtual ~RandomRectanglePosition (); - virtual Vector Get (void) const; -private: - RandomVariable m_x; - RandomVariable m_y; -}; - -/** - * \brief allocate random positions within a disc - * according to a pair of random variables. - */ -class RandomDiscPosition : public RandomPosition -{ -public: - static TypeId GetTypeId (void); - /** - * Create a random position model with construction - * values from \valueref{RandomDiscPositionTheta}, - * \valueref{RandomDiscPositionRho}, - * \valueref{RandomDiscPositionX}, and, - * \valueref{RandomDiscPositionY}. - */ - RandomDiscPosition (); - /** - * \param theta the random variable used to pick - * the angle of the random position in polar - * coordinates. - * \param rho the random variable used to pick the - * radius of the random position in polar - * coordinates. - * \param x the x coordinate of the center of the - * polar coodinate system. - * \param y the y coordinate of the center of the - * polar coodinate system. - */ - RandomDiscPosition (const RandomVariable &theta, - const RandomVariable &rho, - double x, double y); - virtual ~RandomDiscPosition (); - virtual Vector Get (void) const; -private: - RandomVariable m_theta; - RandomVariable m_rho; - double m_x; - double m_y; -}; - -} // namespace ns3 - -#endif /* RANDOM_POSITION_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-walk-2d-mobility-model.cc --- a/src/mobility/random-walk-2d-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-walk-2d-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -19,10 +19,7 @@ * Author: Mathieu Lacage */ #include "random-walk-2d-mobility-model.h" -#include "ns3/default-value.h" -#include "ns3/time-default-value.h" -#include "ns3/rectangle-default-value.h" -#include "ns3/random-variable-default-value.h" +#include "ns3/enum.h" #include "ns3/simulator.h" #include "ns3/log.h" #include @@ -33,113 +30,49 @@ NS_OBJECT_ENSURE_REGISTERED (RandomWalk2dMobilityModel); -static EnumDefaultValue -g_mode ("RandomWalk2dMode", - "The mode indicates the condition used to " - "change the current speed and direction", - RandomWalk2dMobilityModelParameters::MODE_DISTANCE, "Distance", - RandomWalk2dMobilityModelParameters::MODE_TIME, "Time", - 0, (void*)0); - -static NumericDefaultValue -g_modeDistance ("RandomWalk2dDistance", - "Change current direction and speed after moving this distance.", - 2.0); - -static TimeDefaultValue -g_modeTime ("RandomWalk2dTime", - "Change current direction and speed after moving for this delay.", - Seconds (1.0)); - -static RandomVariableDefaultValue -g_speed ("RandomWalk2dSpeed", - "A random variable used to pick the speed.", - "Uniform:2:4"); -static RandomVariableDefaultValue -g_direction ("RandomWalk2dDirection", - "A random variable used to pick the direction (gradients).", - "Uniform:0.0:6.283184"); - -static RectangleDefaultValue -g_rectangle ("RandomWalk2dBounds", - "Bounds of the area to cruise.", - 0.0, 0.0, 100.0, 100.0); - -RandomWalk2dMobilityModelParameters::RandomWalk2dMobilityModelParameters () - : m_mode (g_mode.GetValue ()), - m_modeDistance (g_modeDistance.GetValue ()), - m_modeTime (g_modeTime.GetValue ()), - m_speed (g_speed.Get ()), - m_direction (g_direction.Get ()), - m_bounds (g_rectangle.GetValue ()) -{} - -RandomWalk2dMobilityModelParameters::~RandomWalk2dMobilityModelParameters () -{} - -void -RandomWalk2dMobilityModelParameters::SetSpeed (const RandomVariable &speed) -{ - m_speed = speed; -} -void -RandomWalk2dMobilityModelParameters::SetDirection (const RandomVariable &direction) -{ - m_direction = direction; -} -void -RandomWalk2dMobilityModelParameters::SetModeDistance (double distance) -{ - m_mode = RandomWalk2dMobilityModelParameters::MODE_DISTANCE; - m_modeDistance = distance; -} -void -RandomWalk2dMobilityModelParameters::SetModeTime (Time time) -{ - m_mode = RandomWalk2dMobilityModelParameters::MODE_TIME; - m_modeTime = time; -} -void -RandomWalk2dMobilityModelParameters::SetBounds (const Rectangle &bounds) -{ - m_bounds = bounds; -} - -Ptr -RandomWalk2dMobilityModelParameters::GetCurrent (void) -{ - static Ptr parameters = 0; - if (parameters == 0 || - g_speed.IsDirty () || - g_direction.IsDirty () || - g_mode.IsDirty () || - g_modeDistance.IsDirty () || - g_modeTime.IsDirty () || - g_rectangle.IsDirty ()) - { - parameters = CreateObject (); - } - return parameters; -} - TypeId RandomWalk2dMobilityModel::GetTypeId (void) { static TypeId tid = TypeId ("RandomWalkMobilityModel") .SetParent () + .SetGroupName ("Mobility") .AddConstructor () - .AddConstructor > (); + .AddAttribute ("bounds", + "Bounds of the area to cruise.", + Rectangle (0.0, 0.0, 100.0, 100.0), + MakeRectangleAccessor (&RandomWalk2dMobilityModel::m_bounds), + MakeRectangleChecker ()) + .AddAttribute ("time", + "Change current direction and speed after moving for this delay.", + Seconds (1.0), + MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime), + MakeTimeChecker ()) + .AddAttribute ("distance", + "Change current direction and speed after moving for this distance.", + Seconds (1.0), + MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime), + MakeTimeChecker ()) + .AddAttribute ("mode", + "The mode indicates the condition used to " + "change the current speed and direction", + Enum (RandomWalk2dMobilityModel::MODE_DISTANCE), + MakeEnumAccessor (&RandomWalk2dMobilityModel::m_mode), + MakeEnumChecker (RandomWalk2dMobilityModel::MODE_DISTANCE, "Distance", + RandomWalk2dMobilityModel::MODE_TIME, "Time")) + .AddAttribute ("direction", + "A random variable used to pick the direction (gradients).", + UniformVariable (0.0, 6.283184), + MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_direction), + MakeRandomVariableChecker ()) + .AddAttribute ("speed", + "A random variable used to pick the speed (m/s).", + UniformVariable (2.0, 4.0), + MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_speed), + MakeRandomVariableChecker ()); return tid; } RandomWalk2dMobilityModel::RandomWalk2dMobilityModel () - : m_parameters (RandomWalk2dMobilityModelParameters::GetCurrent ()) -{ - m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this); -} - -RandomWalk2dMobilityModel::RandomWalk2dMobilityModel (Ptr parameters) - : m_parameters (parameters) { m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this); } @@ -147,21 +80,21 @@ void RandomWalk2dMobilityModel::Start (void) { - double speed = m_parameters->m_speed.GetValue (); - double direction = m_parameters->m_direction.GetValue (); + double speed = m_speed.GetValue (); + double direction = m_direction.GetValue (); Vector vector (std::cos (direction) * speed, std::sin (direction) * speed, 0.0); m_helper.Reset (vector); Time delayLeft; - if (m_parameters->m_mode == RandomWalk2dMobilityModelParameters::MODE_TIME) + if (m_mode == RandomWalk2dMobilityModel::MODE_TIME) { - delayLeft = m_parameters->m_modeTime; + delayLeft = m_modeTime; } else { - delayLeft = Seconds (m_parameters->m_modeDistance / speed); + delayLeft = Seconds (m_modeDistance / speed); } DoWalk (delayLeft); } @@ -174,13 +107,13 @@ Vector nextPosition = position; nextPosition.x += speed.x * delayLeft.GetSeconds (); nextPosition.y += speed.y * delayLeft.GetSeconds (); - if (m_parameters->m_bounds.IsInside (nextPosition)) + if (m_bounds.IsInside (nextPosition)) { m_event = Simulator::Schedule (delayLeft, &RandomWalk2dMobilityModel::Start, this); } else { - nextPosition = m_parameters->m_bounds.CalculateIntersection (position, speed); + nextPosition = m_bounds.CalculateIntersection (position, speed); Time delay = Seconds ((nextPosition.x - position.x) / speed.x); m_event = Simulator::Schedule (delay, &RandomWalk2dMobilityModel::Rebound, this, delayLeft - delay); @@ -191,9 +124,9 @@ void RandomWalk2dMobilityModel::Rebound (Time delayLeft) { - Vector position = m_helper.GetCurrentPosition (m_parameters->m_bounds); + Vector position = m_helper.GetCurrentPosition (m_bounds); Vector speed = m_helper.GetVelocity (); - switch (m_parameters->m_bounds.GetClosestSide (position)) + switch (m_bounds.GetClosestSide (position)) { case Rectangle::RIGHT: case Rectangle::LEFT: @@ -211,19 +144,18 @@ void RandomWalk2dMobilityModel::DoDispose (void) { - m_parameters = 0; // chain up MobilityModel::DoDispose (); } Vector RandomWalk2dMobilityModel::DoGetPosition (void) const { - return m_helper.GetCurrentPosition (m_parameters->m_bounds); + return m_helper.GetCurrentPosition (m_bounds); } void RandomWalk2dMobilityModel::DoSetPosition (const Vector &position) { - NS_ASSERT (m_parameters->m_bounds.IsInside (position)); + NS_ASSERT (m_bounds.IsInside (position)); m_helper.InitializePosition (position); Simulator::Remove (m_event); m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this); diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-walk-2d-mobility-model.h --- a/src/mobility/random-walk-2d-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-walk-2d-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -33,72 +33,6 @@ /** - * \brief parameters to control a random walk 2d model - * - * A single parameter object can be shared by multiple random - * walk models. - */ -class RandomWalk2dMobilityModelParameters : public Object -{ - public: - /** - * Instantiate a set of RandomWalk parameters initialized - * with construction values from \valueref{RandomWalk2dMode}, - * \valueref{RandomWalk2dDistance}, \valueref{RandomWalk2dTime}, - * \valueref{RandomWalk2dSpeed}, \valueref{RandomWalk2dDirection}, - * and, \valueref{RandomWalk2dBounds}. - */ - RandomWalk2dMobilityModelParameters (); - virtual ~RandomWalk2dMobilityModelParameters (); - /** - * \param speed the random variable used to pick a new - * speed when the direction is changed. - * - */ - void SetSpeed (const RandomVariable &speed); - /** - * \param direction the random variable used to pick a new - * direction. - */ - void SetDirection (const RandomVariable &direction); - /** - * \param distance the distance before a direction change - * - * Unit is meters. - * "time" mode is incompatible with "distance" mode. - */ - void SetModeDistance (double distance); - /** - * \param time the delay before a direction change. - * - * "time" mode is incompatible with "distance" mode. - */ - void SetModeTime (Time time); - - /** - * \param bounds the bounds of the random walk - */ - void SetBounds (const Rectangle &bounds); - - - // needed public for internal default value code. - enum Mode { - MODE_DISTANCE, - MODE_TIME - }; - private: - friend class RandomWalk2dMobilityModel; - static Ptr GetCurrent (void); - - enum Mode m_mode; - double m_modeDistance; - Time m_modeTime; - RandomVariable m_speed; - RandomVariable m_direction; - Rectangle m_bounds; -}; - -/** * \brief a 2D random walk position model * * Each instance moves with a speed and direction choosen at random @@ -116,6 +50,12 @@ { public: static TypeId GetTypeId (void); + + enum Mode { + MODE_DISTANCE, + MODE_TIME + }; + /** * Instantiate a set of RandomWalk parameters initialized * with construction values from \valueref{RandomWalk2dMode}, @@ -126,14 +66,6 @@ * The default position is (0,0,0) */ RandomWalk2dMobilityModel (); - /** - * \param parameters the parameters to use to control - * the movement of this mobile object. - * - * Create a new position object located at position (0,0,0) with - * the specified parameters. - */ - RandomWalk2dMobilityModel (Ptr parameters); private: void Start (void); @@ -146,7 +78,12 @@ StaticSpeedHelper m_helper; EventId m_event; - Ptr m_parameters; + enum Mode m_mode; + double m_modeDistance; + Time m_modeTime; + RandomVariable m_speed; + RandomVariable m_direction; + Rectangle m_bounds; }; diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-waypoint-mobility-model.cc --- a/src/mobility/random-waypoint-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-waypoint-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -23,106 +23,49 @@ #include "ns3/random-variable-default-value.h" #include "ns3/type-id-default-value.h" #include "random-waypoint-mobility-model.h" -#include "random-position.h" +#include "position-allocator.h" namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (RandomWaypointMobilityModel); -static RandomVariableDefaultValue -g_speed ("RandomWaypointSpeed", - "A random variable used to pick the speed of a random waypoint model.", - "Uniform:0.3:0.7"); - -static RandomVariableDefaultValue -g_pause ("RandomWaypointPause", - "A random variable used to pick the pause of a random waypoint model.", - "Constant:2"); - -static TypeIdDefaultValue -g_position ("RandomWaypointPosition", - "A random position model used to pick the next waypoint position.", - RandomPosition::GetTypeId (), - "RandomRectanglePosition"); - - -RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters () - : m_speed (g_speed.Get ()), - m_pause (g_pause.Get ()) -{ - m_position = g_position.GetValue ().CreateObject ()->GetObject (); -} -RandomWaypointMobilityModelParameters::RandomWaypointMobilityModelParameters (Ptr randomPosition, - const RandomVariable &speed, - const RandomVariable &pause) - : m_speed (speed), - m_pause (pause), - m_position (randomPosition) -{} -void -RandomWaypointMobilityModelParameters::SetWaypointPositionModel (Ptr randomPosition) -{ - m_position = randomPosition; -} -void -RandomWaypointMobilityModelParameters::SetSpeed (const RandomVariable &speed) -{ - m_speed = speed; -} -void -RandomWaypointMobilityModelParameters::SetPause (const RandomVariable &pause) -{ - m_pause = pause; -} -void -RandomWaypointMobilityModelParameters::DoDispose (void) -{ - m_position = 0; -} - -Ptr -RandomWaypointMobilityModelParameters::GetCurrent (void) -{ - static Ptr parameters = 0; - if (parameters == 0 || - g_position.IsDirty () || - g_pause.IsDirty () || - g_speed.IsDirty ()) - { - parameters = CreateObject (); - } - return parameters; -} - TypeId RandomWaypointMobilityModel::GetTypeId (void) { static TypeId tid = TypeId ("RandomWaypointMobilityModel") .SetParent () + .SetGroupName ("Mobility") .AddConstructor () - .AddConstructor > (); + .AddAttribute ("speed", + "A random variable used to pick the speed of a random waypoint model.", + UniformVariable (0.3, 0.7), + MakeRandomVariableAccessor (&RandomWaypointMobilityModel::m_speed), + MakeRandomVariableChecker ()) + .AddAttribute ("pause", + "A random variable used to pick the pause of a random waypoint model.", + ConstantVariable (2.0), + MakeRandomVariableAccessor (&RandomWaypointMobilityModel::m_pause), + MakeRandomVariableChecker ()) + .AddAttribute ("position", + "The position model used to pick a destination point.", + Ptr (0), + MakePtrAccessor (&RandomWaypointMobilityModel::m_position), + MakePtrChecker ()); + return tid; } RandomWaypointMobilityModel::RandomWaypointMobilityModel () - : m_parameters (RandomWaypointMobilityModelParameters::GetCurrent ()) { Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this); } -RandomWaypointMobilityModel::RandomWaypointMobilityModel (Ptr parameters) - : m_parameters (parameters) -{ - Simulator::ScheduleNow (&RandomWaypointMobilityModel::Start, this); - NotifyCourseChange (); -} - void RandomWaypointMobilityModel::BeginWalk (void) { Vector m_current = m_helper.GetCurrentPosition (); - Vector destination = m_parameters->m_position->Get (); - double speed = m_parameters->m_speed.GetValue (); + Vector destination = m_position->GetNext (); + double speed = m_speed.GetValue (); double dx = (destination.x - m_current.x); double dy = (destination.y - m_current.y); double dz = (destination.z - m_current.z); @@ -138,7 +81,7 @@ void RandomWaypointMobilityModel::Start (void) { - Time pause = Seconds (m_parameters->m_pause.GetValue ()); + Time pause = Seconds (m_pause.GetValue ()); m_helper.Pause (); NotifyCourseChange (); m_event = Simulator::Schedule (pause, &RandomWaypointMobilityModel::BeginWalk, this); diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/random-waypoint-mobility-model.h --- a/src/mobility/random-waypoint-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/random-waypoint-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -23,54 +23,13 @@ #include "static-speed-helper.h" #include "mobility-model.h" -#include "random-position.h" +#include "position-allocator.h" #include "ns3/ptr.h" #include "ns3/random-variable.h" namespace ns3 { /** - * \brief the parameters which control the behavior of a random waypoint - * mobility model. - */ -class RandomWaypointMobilityModelParameters : public Object -{ -public: - /** - * Default parameters from \valueref{RandomWaypointPause}, - * and, \valueref{RandomWaypointPosition}. - */ - RandomWaypointMobilityModelParameters (); - /** - * \param randomPosition a random position model to choose the position of waypoints. - * \param speed a random variable to choose the speed - * \param pause a random variable to choose the pause delay - */ - RandomWaypointMobilityModelParameters (Ptr randomPosition, - const RandomVariable &speed, - const RandomVariable &pause); - /** - * \param randomPosition a random position model to choose the position of waypoints. - */ - void SetWaypointPositionModel (Ptr randomPosition); - /** - * \param speed a random variable to choose the speed - */ - void SetSpeed (const RandomVariable &speed); - /** - * \param pause a random variable to choose the pause delay - */ - void SetPause (const RandomVariable &pause); -private: - friend class RandomWaypointMobilityModel; - static Ptr GetCurrent (void); - virtual void DoDispose (void); - RandomVariable m_speed; - RandomVariable m_pause; - Ptr m_position; -}; - -/** * \brief a random waypoint mobility model * * Each object chooses a random destination "waypoint", a random speed, @@ -86,15 +45,7 @@ { public: static TypeId GetTypeId (void); - /** - * Default parameters from \valueref{RandomWaypointPause}, - * and, \valueref{RandomWaypointPosition}. - */ RandomWaypointMobilityModel (); - /** - * \param parameters the parameters which control the behavior of this model. - */ - RandomWaypointMobilityModel (Ptr parameters); private: void Start (void); void BeginWalk (void); @@ -103,7 +54,9 @@ virtual Vector DoGetVelocity (void) const; StaticSpeedHelper m_helper; - Ptr m_parameters; + Ptr m_position; + RandomVariable m_speed; + RandomVariable m_pause; EventId m_event; }; diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/rectangle.cc --- a/src/mobility/rectangle.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/rectangle.cc Wed Feb 27 22:19:39 2008 +0100 @@ -20,8 +20,10 @@ #include "rectangle.h" #include "vector.h" #include "ns3/assert.h" +#include "ns3/fatal-error.h" #include #include +#include namespace ns3 { @@ -117,5 +119,27 @@ } +VALUE_HELPER_CPP (Rectangle); + +std::ostream & +operator << (std::ostream &os, const Rectangle &rectangle) +{ + os << rectangle.xMin << "|" << rectangle.xMax << "|" << rectangle.yMin << "|" << rectangle.yMax; + return os; +} +std::istream & +operator >> (std::istream &is, Rectangle &rectangle) + { + char c1, c2, c3; + is >> rectangle.xMin >> c1 >> rectangle.xMax >> c2 >> rectangle.yMin >> c3 >> rectangle.yMax; + if (c1 != '|' || + c2 != '|' || + c3 != '|') + { + is.setstate (std::ios_base::failbit); + } + return is; +} + } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/rectangle.h --- a/src/mobility/rectangle.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/rectangle.h Wed Feb 27 22:19:39 2008 +0100 @@ -20,6 +20,9 @@ #ifndef RECTANGLE_H #define RECTANGLE_H +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" + namespace ns3 { class Vector; @@ -58,8 +61,15 @@ double xMax; double yMin; double yMax; + + VALUE_HELPER_HEADER_1 (Rectangle); }; +std::ostream &operator << (std::ostream &os, const Rectangle &rectangle); +std::istream &operator >> (std::istream &is, Rectangle &rectangle); + +VALUE_HELPER_HEADER_2 (Rectangle); + } // namespace ns3 #endif /* RECTANGLE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/static-mobility-model.cc --- a/src/mobility/static-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/static-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -29,15 +29,12 @@ static TypeId tid = TypeId ("StaticMobilityModel") .SetParent () .AddConstructor () - .AddConstructor (); + ; return tid; } StaticMobilityModel::StaticMobilityModel () {} -StaticMobilityModel::StaticMobilityModel (const Vector &position) - : m_position (position) -{} StaticMobilityModel::~StaticMobilityModel () {} diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/static-mobility-model.h --- a/src/mobility/static-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/static-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -21,6 +21,7 @@ #define STATIC_MOBILITY_MODEL_H #include "mobility-model.h" +#include "vector.h" namespace ns3 { @@ -37,13 +38,6 @@ * Create a position located at coordinates (0,0,0) */ StaticMobilityModel (); - /** - * \param position the initial position. - * - * Create a position located at coordinates (x,y,z). - * Unit is meters - */ - StaticMobilityModel (const Vector &position); virtual ~StaticMobilityModel (); private: diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/static-speed-mobility-model.cc --- a/src/mobility/static-speed-mobility-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/static-speed-mobility-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -28,21 +28,12 @@ { static TypeId tid = TypeId ("StaticSpeedMobilityModel") .SetParent () - .AddConstructor () - .AddConstructor () - .AddConstructor (); + .AddConstructor (); return tid; } StaticSpeedMobilityModel::StaticSpeedMobilityModel () {} -StaticSpeedMobilityModel::StaticSpeedMobilityModel (const Vector &position) - : m_helper (position) -{} -StaticSpeedMobilityModel::StaticSpeedMobilityModel (const Vector &position, - const Vector &speed) - : m_helper (position, speed) -{} StaticSpeedMobilityModel::~StaticSpeedMobilityModel () {} diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/static-speed-mobility-model.h --- a/src/mobility/static-speed-mobility-model.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/static-speed-mobility-model.h Wed Feb 27 22:19:39 2008 +0100 @@ -41,19 +41,6 @@ * speed (0,0,0). */ StaticSpeedMobilityModel (); - /** - * Create a position located at coordinates (x,y,z) with - * speed (0,0,0). - */ - StaticSpeedMobilityModel (const Vector &position); - /** - * - * Create a position located at coordinates (x,y,z) with - * speed (dx,dy,dz). - * Unit is meters and meters/s - */ - StaticSpeedMobilityModel (const Vector &position, - const Vector &speed); virtual ~StaticSpeedMobilityModel (); /** diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/vector.cc --- a/src/mobility/vector.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/vector.cc Wed Feb 27 22:19:39 2008 +0100 @@ -18,10 +18,14 @@ * Author: Mathieu Lacage */ #include "vector.h" +#include "ns3/fatal-error.h" #include +#include namespace ns3 { +VALUE_HELPER_CPP (Vector); + Vector::Vector (double _x, double _y, double _z) : x (_x), @@ -45,4 +49,21 @@ return distance; } +std::ostream &operator << (std::ostream &os, const Vector &vector) +{ + os << vector.x << ":" << vector.y << ":" << vector.z; + return os; +} +std::istream &operator >> (std::istream &is, Vector &vector) +{ + char c1, c2; + is >> vector.x >> c1 >> vector.y >> c2 >> vector.z; + if (c1 != ':' || + c2 != ':') + { + is.setstate (std::ios_base::failbit); + } + return is; +} + } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/vector.h --- a/src/mobility/vector.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/vector.h Wed Feb 27 22:19:39 2008 +0100 @@ -20,6 +20,9 @@ #ifndef VECTOR_H #define VECTOR_H +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" + namespace ns3 { /** @@ -54,10 +57,17 @@ * z coordinate of vector vector */ double z; + + VALUE_HELPER_HEADER_1 (Vector); }; double CalculateDistance (const Vector &a, const Vector &b); +VALUE_HELPER_HEADER_2 (Vector); + +std::ostream &operator << (std::ostream &os, const Vector &vector); +std::istream &operator >> (std::istream &is, Vector &vector); + } // namespace ns3 #endif /* VECTOR_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/mobility/wscript --- a/src/mobility/wscript Tue Feb 26 01:39:59 2008 +0100 +++ b/src/mobility/wscript Wed Feb 27 22:19:39 2008 +0100 @@ -4,12 +4,10 @@ mobility = bld.create_ns3_module('mobility', ['core', 'simulator']) mobility.source = [ 'vector.cc', - 'grid-topology.cc', 'hierarchical-mobility-model.cc', 'mobility-model.cc', 'mobility-model-notifier.cc', - 'random-position.cc', - 'random-topology.cc', + 'position-allocator.cc', 'rectangle.cc', 'rectangle-default-value.cc', 'static-mobility-model.cc', @@ -18,18 +16,17 @@ 'random-waypoint-mobility-model.cc', 'random-walk-2d-mobility-model.cc', 'random-direction-2d-mobility-model.cc', - 'ns2-mobility-file-topology.cc', + 'ns2-mobility-helper.cc', + 'mobility-helper.cc', ] headers = bld.create_obj('ns3header') headers.source = [ 'vector.h', - 'grid-topology.h', 'hierarchical-mobility-model.h', 'mobility-model.h', 'mobility-model-notifier.h', - 'random-position.h', - 'random-topology.h', + 'position-allocator.h', 'rectangle.h', 'rectangle-default-value.h', 'static-mobility-model.h', @@ -38,5 +35,6 @@ 'random-waypoint-mobility-model.h', 'random-walk-2d-mobility-model.h', 'random-direction-2d-mobility-model.h', - 'ns2-mobility-file-topology.h', + 'ns2-mobility-helper.h', + 'mobility-helper.h', ] diff -r d64b1561b1c2 -r e667dc0f350e src/node/address.cc --- a/src/node/address.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/address.cc Wed Feb 27 22:19:39 2008 +0100 @@ -107,6 +107,8 @@ return type; } +VALUE_HELPER_CPP (Address); + bool operator == (const Address &a, const Address &b) { NS_ASSERT (a.m_type == b.m_type || @@ -159,6 +161,12 @@ return os; } +std::istream& operator>> (std::istream& is, Address & address) +{ + // XXX: need to be able to parse this. + return is; +} + } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/address.h --- a/src/node/address.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/address.h Wed Feb 27 22:19:39 2008 +0100 @@ -3,6 +3,8 @@ #include #include +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" namespace ns3 { @@ -151,6 +153,8 @@ * \returns a new type id. */ static uint8_t Register (void); + + VALUE_HELPER_HEADER_1 (Address); private: friend bool operator == (const Address &a, const Address &b); friend bool operator < (const Address &a, const Address &b); @@ -161,12 +165,15 @@ uint8_t m_data[MAX_SIZE]; }; +VALUE_HELPER_HEADER_2 (Address); + bool operator == (const Address &a, const Address &b); bool operator != (const Address &a, const Address &b); bool operator < (const Address &a, const Address &b); std::ostream& operator<< (std::ostream& os, const Address & address); +std::istream& operator>> (std::istream& is, Address & address); + } // namespace ns3 - #endif /* ADDRESS_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/application.cc --- a/src/node/application.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/application.cc Wed Feb 27 22:19:39 2008 +0100 @@ -31,14 +31,26 @@ namespace ns3 { +NS_OBJECT_ENSURE_REGISTERED (Application); + // Application Methods +TypeId +Application::GetTypeId (void) +{ + static TypeId tid = TypeId ("Application") + .SetParent () + .AddAttribute ("Node", "The on which this application resides", + Ptr (0), + MakePtrAccessor (&Application::m_node), + MakePtrChecker ()) + ; + return tid; +} + // \brief Application Constructor -Application::Application(Ptr n) - : m_node (n) -{ - m_node->AddApplication (this); -} +Application::Application() +{} // \brief Application Destructor Application::~Application() diff -r d64b1561b1c2 -r e667dc0f350e src/node/application.h --- a/src/node/application.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/application.h Wed Feb 27 22:19:39 2008 +0100 @@ -52,7 +52,8 @@ class Application : public Object { public: - Application(Ptr); + static TypeId GetTypeId (void); + Application(); virtual ~Application(); /** diff -r d64b1561b1c2 -r e667dc0f350e src/node/drop-tail-queue.cc --- a/src/node/drop-tail-queue.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/drop-tail-queue.cc Wed Feb 27 22:19:39 2008 +0100 @@ -18,6 +18,7 @@ */ #include "ns3/log.h" +#include "ns3/uinteger.h" #include "drop-tail-queue.h" NS_LOG_COMPONENT_DEFINE ("DropTailQueue"); @@ -30,14 +31,19 @@ { static TypeId tid = TypeId ("DropTailQueue") .SetParent () - .AddConstructor (); + .AddConstructor () + .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this DropTailQueue.", + Uinteger (100), + MakeUintegerAccessor (&DropTailQueue::m_maxPackets), + MakeUintegerChecker ()) + ; + return tid; } DropTailQueue::DropTailQueue () : Queue (), - m_packets (), - m_maxPackets(DTQ_NPACKETS_MAX_DEFAULT) + m_packets () { NS_LOG_FUNCTION; } @@ -47,22 +53,6 @@ NS_LOG_FUNCTION; } -void -DropTailQueue::SetMaxPackets (uint32_t npackets) -{ - NS_LOG_FUNCTION; - NS_LOG_PARAMS (this << npackets); - m_maxPackets = npackets; -} - -uint32_t -DropTailQueue::GetMaxPackets (void) -{ - NS_LOG_FUNCTION; - NS_LOG_LOGIC ("returns " << m_maxPackets); - return m_maxPackets; -} - bool DropTailQueue::DoEnqueue (Ptr p) { @@ -142,8 +132,8 @@ { bool result = true; - DropTailQueue queue; - queue.SetMaxPackets (3); + Ptr queue = CreateObject (); + NS_TEST_ASSERT (queue->SetAttribute ("MaxPackets", Uinteger (3))); Ptr p1, p2, p3, p4; p1 = Create (); @@ -151,34 +141,34 @@ p3 = Create (); p4 = Create (); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 0); - queue.Enqueue (p1); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 1); - queue.Enqueue (p2); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 2); - queue.Enqueue (p3); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 3); - queue.Enqueue (p4); // will be dropped - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 3); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 0); + queue->Enqueue (p1); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 1); + queue->Enqueue (p2); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 2); + queue->Enqueue (p3); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 3); + queue->Enqueue (p4); // will be dropped + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 3); Ptr p; - p = queue.Dequeue (); + p = queue->Dequeue (); NS_TEST_ASSERT (p != 0); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 2); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 2); NS_TEST_ASSERT_EQUAL (p->GetUid (), p1->GetUid ()); - p = queue.Dequeue (); + p = queue->Dequeue (); NS_TEST_ASSERT (p != 0); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 1); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 1); NS_TEST_ASSERT_EQUAL (p->GetUid (), p2->GetUid ()); - p = queue.Dequeue (); + p = queue->Dequeue (); NS_TEST_ASSERT (p != 0); - NS_TEST_ASSERT_EQUAL (queue.GetNPackets (), 0); + NS_TEST_ASSERT_EQUAL (queue->GetNPackets (), 0); NS_TEST_ASSERT_EQUAL (p->GetUid (), p3->GetUid ()); - p = queue.Dequeue (); + p = queue->Dequeue (); NS_TEST_ASSERT (p == 0); return result; diff -r d64b1561b1c2 -r e667dc0f350e src/node/drop-tail-queue.h --- a/src/node/drop-tail-queue.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/drop-tail-queue.h Wed Feb 27 22:19:39 2008 +0100 @@ -28,8 +28,6 @@ class TraceContainer; -const int DTQ_NPACKETS_MAX_DEFAULT = 100; - /** * \brief A FIFO packet queue that drops tail-end packets on overflow */ @@ -44,16 +42,6 @@ DropTailQueue (); virtual ~DropTailQueue(); - /** - * \param npackets The maximum number of packets this queue will hold before - * dropping packets. - */ - void SetMaxPackets (uint32_t npackets); - /** - * \return The maximum number of packets this queue will hold before dropping - * packets. - */ - uint32_t GetMaxPackets (void); private: virtual bool DoEnqueue (Ptr p); diff -r d64b1561b1c2 -r e667dc0f350e src/node/ipv4-address.cc --- a/src/node/ipv4-address.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/ipv4-address.cc Wed Feb 27 22:19:39 2008 +0100 @@ -301,6 +301,21 @@ mask.Print (os); return os; } +std::istream & operator >> (std::istream &is, Ipv4Address &address) +{ + std::string str; + is >> str; + address = Ipv4Address (str.c_str ()); + return is; +} +std::istream & operator >> (std::istream &is, Ipv4Mask &mask) +{ + std::string str; + is >> str; + mask = Ipv4Mask (str.c_str ()); + return is; +} + bool operator == (Ipv4Mask const &a, Ipv4Mask const &b) { return a.IsEqual (b); @@ -310,5 +325,7 @@ return !a.IsEqual (b); } +VALUE_HELPER_CPP (Ipv4Address); +VALUE_HELPER_CPP (Ipv4Mask); -}; // namespace ns3 +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/ipv4-address.h --- a/src/node/ipv4-address.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/ipv4-address.h Wed Feb 27 22:19:39 2008 +0100 @@ -25,6 +25,7 @@ #include #include #include "address.h" +#include "ns3/attribute-helper.h" namespace ns3 { @@ -141,6 +142,8 @@ static Ipv4Address GetAny (void); static Ipv4Address GetBroadcast (void); static Ipv4Address GetLoopback (void); + + VALUE_HELPER_HEADER_1 (Ipv4Address); private: Address ConvertTo (void) const; static uint8_t GetType (void); @@ -177,12 +180,19 @@ static Ipv4Mask GetLoopback (void); static Ipv4Mask GetZero (void); + + VALUE_HELPER_HEADER_1 (Ipv4Mask); private: uint32_t m_mask; }; +VALUE_HELPER_HEADER_2 (Ipv4Address); +VALUE_HELPER_HEADER_2 (Ipv4Mask); + std::ostream& operator<< (std::ostream& os, Ipv4Address const& address); std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask); +std::istream & operator >> (std::istream &is, Ipv4Address &address); +std::istream & operator >> (std::istream &is, Ipv4Mask &mask); inline bool operator == (const Ipv4Address &a, const Ipv4Address &b) { @@ -206,6 +216,6 @@ bool operator == (Ipv4Mask const &a, Ipv4Mask const &b); bool operator != (Ipv4Mask const &a, Ipv4Mask const &b); -}; // namespace ns3 +} // namespace ns3 #endif /* IPV4_ADDRESS_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/mac48-address.cc --- a/src/node/mac48-address.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/mac48-address.cc Wed Feb 27 22:19:39 2008 +0100 @@ -25,6 +25,8 @@ namespace ns3 { +VALUE_HELPER_CPP (Mac48Address); + #define ASCII_a (0x41) #define ASCII_z (0x5a) #define ASCII_A (0x61) @@ -149,6 +151,7 @@ static Mac48Address broadcast = Mac48Address ("ff:ff:ff:ff:ff:ff"); return broadcast; } + bool operator == (const Mac48Address &a, const Mac48Address &b) { return memcmp (a.m_address, b.m_address, 6) == 0; @@ -197,5 +200,11 @@ return os; } +std::istream& operator>> (std::istream& is, const Mac48Address & address) +{ + // XXX ! + return is; +} + } // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/mac48-address.h --- a/src/node/mac48-address.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/mac48-address.h Wed Feb 27 22:19:39 2008 +0100 @@ -17,11 +17,13 @@ * * Author: Mathieu Lacage */ -#ifndef EUI48_ADDRESS_H -#define EUI48_ADDRESS_H +#ifndef MAC48_ADDRESS_H +#define MAC48_ADDRESS_H #include #include +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" namespace ns3 { @@ -93,6 +95,8 @@ * \returns the broadcast address */ static Mac48Address GetBroadcast (void); + + VALUE_HELPER_HEADER_1 (Mac48Address); private: /** * \returns a new Address instance @@ -107,11 +111,14 @@ uint8_t m_address[6]; }; +VALUE_HELPER_HEADER_2 (Mac48Address); + bool operator == (const Mac48Address &a, const Mac48Address &b); bool operator != (const Mac48Address &a, const Mac48Address &b); bool operator < (const Mac48Address &a, const Mac48Address &b); std::ostream& operator<< (std::ostream& os, const Mac48Address & address); +std::istream& operator>> (std::istream& is, const Mac48Address & address); } // namespace ns3 -#endif /* EUI48_ADDRESS_H */ +#endif /* MAC48_ADDRESS_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/mac64-address.h --- a/src/node/mac64-address.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/mac64-address.h Wed Feb 27 22:19:39 2008 +0100 @@ -17,8 +17,8 @@ * * Author: Mathieu Lacage */ -#ifndef EUI64_ADDRESS_H -#define EUI64_ADDRESS_H +#ifndef MAC64_ADDRESS_H +#define MAC64_ADDRESS_H #include #include @@ -95,4 +95,4 @@ } // namespace ns3 -#endif /* EUI64_ADDRESS_H */ +#endif /* MAC64_ADDRESS_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/net-device-container.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/node/net-device-container.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,40 @@ +#include "net-device-container.h" + +namespace ns3 { + +NetDeviceContainer::Iterator +NetDeviceContainer::Begin (void) const +{ + return m_nodes.begin (); +} +NetDeviceContainer::Iterator +NetDeviceContainer::End (void) const +{ + return m_nodes.end (); +} + +uint32_t +NetDeviceContainer::GetN (void) const +{ + return m_nodes.size (); +} +Ptr +NetDeviceContainer::Get (uint32_t i) const +{ + return m_nodes[i]; +} +void +NetDeviceContainer::Add (NetDeviceContainer other) +{ + for (Iterator i = other.Begin (); i != other.End (); i++) + { + m_nodes.push_back (*i); + } +} +void +NetDeviceContainer::Add (Ptr node) +{ + m_nodes.push_back (node); +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/net-device-container.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/node/net-device-container.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,31 @@ +#ifndef NET_DEVICE_CONTAINER_H +#define NET_DEVICE_CONTAINER_H + +#include +#include +#include "net-device.h" + +namespace ns3 { + +class NetDeviceContainer +{ +public: + typedef std::vector >::const_iterator Iterator; + + Iterator Begin (void) const; + Iterator End (void) const; + + uint32_t GetN (void) const; + Ptr Get (uint32_t i) const; + + void Create (uint32_t n); + void Add (NetDeviceContainer other); + void Add (Ptr node); + +private: + std::vector > m_nodes; +}; + +} // namespace ns3 + +#endif /* NET_DEVICE_CONTAINER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/net-device.cc --- a/src/node/net-device.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/net-device.cc Wed Feb 27 22:19:39 2008 +0100 @@ -19,15 +19,9 @@ * Author: Mathieu Lacage */ -#include -#include "ns3/assert.h" #include "ns3/object.h" #include "ns3/log.h" -#include "ns3/trace-resolver.h" -#include "ns3/packet.h" -#include "channel.h" #include "net-device.h" -#include "node.h" NS_LOG_COMPONENT_DEFINE ("NetDevice"); @@ -42,272 +36,7 @@ return tid; } -NetDevice::NetDevice(Ptr node, const Address& addr) : - m_node (node), - m_name(""), - m_ifIndex (0), - m_address (addr), - m_mtu (0xffff), - m_isUp (false), - m_isBroadcast (false), - m_isMulticast (false), - m_isPointToPoint (false) -{ - NS_LOG_FUNCTION; - m_node->AddDevice (this); -} - NetDevice::~NetDevice () -{ - NS_LOG_FUNCTION; -} - -Address -NetDevice::GetAddress (void) const -{ - NS_LOG_FUNCTION; - return m_address; -} - -bool -NetDevice::SetMtu (const uint16_t mtu) -{ - NS_LOG_FUNCTION; - m_mtu = mtu; - return true; -} - -uint16_t -NetDevice::GetMtu (void) const -{ - NS_LOG_FUNCTION; - return m_mtu; -} - -void -NetDevice::SetName(const std::string name) -{ - NS_LOG_FUNCTION; - m_name = name; -} - -std::string -NetDevice::GetName(void) const -{ - NS_LOG_FUNCTION; - return m_name; -} - -void -NetDevice::SetIfIndex(uint32_t index) -{ - NS_LOG_FUNCTION; - m_ifIndex = index; -} - -uint32_t -NetDevice::GetIfIndex(void) const -{ - NS_LOG_FUNCTION; - return m_ifIndex; -} - -bool -NetDevice::IsLinkUp (void) const -{ - NS_LOG_FUNCTION; - return m_isUp; -} - -void -NetDevice::SetLinkChangeCallback (Callback callback) -{ - NS_LOG_FUNCTION; - m_linkChangeCallback = callback; -} - -bool -NetDevice::IsBroadcast (void) const -{ - NS_LOG_FUNCTION; - return m_isBroadcast; -} - -Address const & -NetDevice::GetBroadcast (void) const -{ - NS_LOG_FUNCTION; - NS_ASSERT (m_isBroadcast); - return m_broadcast; -} - -void -NetDevice::EnableBroadcast (Address broadcast) -{ - NS_LOG_FUNCTION; - m_isBroadcast = true; - m_broadcast = broadcast; -} - -void -NetDevice::DisableBroadcast (void) -{ - NS_LOG_FUNCTION; - m_isBroadcast = false; -} - -bool -NetDevice::IsMulticast (void) const -{ - NS_LOG_FUNCTION; - return m_isMulticast; -} - -Address -NetDevice::GetMulticast (void) const -{ - NS_LOG_FUNCTION; - NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " - "Invalid operation when not IsMulticast ()"); - return m_multicast; -} +{} -Address -NetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const -{ - NS_LOG_FUNCTION; - NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): " - "Invalid operation when not IsMulticast ()"); - return m_multicast; -} - -void -NetDevice::EnableMulticast (Address multicast) -{ - NS_LOG_FUNCTION; - m_isMulticast = true; - m_multicast = multicast; -} - -void -NetDevice::DisableMulticast (void) -{ - NS_LOG_FUNCTION; - m_isMulticast = false; -} - -bool -NetDevice::IsPointToPoint (void) const -{ - NS_LOG_FUNCTION; - return m_isPointToPoint; -} - -void -NetDevice::EnablePointToPoint (void) -{ - NS_LOG_FUNCTION; - m_isPointToPoint = true; -} - -void -NetDevice::DisablePointToPoint (void) -{ - NS_LOG_FUNCTION; - m_isPointToPoint = false; -} - -// Receive packet from above -bool -NetDevice::Send(Ptr p, const Address& dest, uint16_t protocolNumber) -{ - NS_LOG_FUNCTION; - if (m_isUp) - { - return SendTo(p, dest, protocolNumber); - } - else - { - return false; - } -} - -Ptr -NetDevice::GetChannel (void) const -{ - NS_LOG_FUNCTION; - return DoGetChannel (); -} - -// Receive packets from below -bool -NetDevice::ForwardUp(Ptr p, uint16_t param, const Address &from) -{ - NS_LOG_FUNCTION; - bool retval = false; - - NS_LOG_LOGIC ("UID is " << p->GetUid() << " device is: " << GetName()); - - if (!m_receiveCallback.IsNull ()) - { - retval = m_receiveCallback (this, p, param, from); - } - else - { - NS_LOG_WARN ("NetDevice::Receive call back is NULL"); - } - - return retval; -} - -void -NetDevice::NotifyLinkUp (void) -{ - NS_LOG_FUNCTION; - m_isUp = true; - if (!m_linkChangeCallback.IsNull ()) - { - m_linkChangeCallback (); - } -} - -void -NetDevice::NotifyLinkDown (void) -{ - NS_LOG_FUNCTION; - m_isUp = false; - if (!m_linkChangeCallback.IsNull ()) - { - m_linkChangeCallback (); - } -} - -Ptr -NetDevice::GetNode (void) const -{ - NS_LOG_FUNCTION; - return m_node; -} - -bool -NetDevice::NeedsArp (void) const -{ - NS_LOG_FUNCTION; - return DoNeedsArp (); -} - -void -NetDevice::SetReceiveCallback (ReceiveCallback cb) -{ - NS_LOG_FUNCTION; - m_receiveCallback = cb; -} - -void -NetDevice::DoDispose() -{ - NS_LOG_FUNCTION; - m_node = 0; -} - -}; // namespace ns3 +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/net-device.h --- a/src/node/net-device.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/net-device.h Wed Feb 27 22:19:39 2008 +0100 @@ -63,52 +63,53 @@ static TypeId GetTypeId (void); virtual ~NetDevice(); + /** + * \param name name of the device (e.g. "eth0") + */ + virtual void SetName(const std::string name) = 0; + /** + * \return name name of the device (e.g. "eth0") + */ + virtual std::string GetName(void) const = 0; + /** + * \param index ifIndex of the device + */ + virtual void SetIfIndex(const uint32_t index) = 0; + /** + * \return index ifIndex of the device + */ + virtual uint32_t GetIfIndex(void) const = 0; + /** * \return the channel this NetDevice is connected to. The value * returned can be zero if the NetDevice is not yet connected * to any channel. */ - Ptr GetChannel (void) const; + virtual Ptr GetChannel (void) const = 0; /** * \return the current Address of this interface. */ - Address GetAddress (void) const; + virtual Address GetAddress (void) const = 0; /** * \param mtu MTU value, in bytes, to set for the device * \return whether the MTU value was within legal bounds * * Override for default MTU defined on a per-type basis. */ - bool SetMtu (const uint16_t mtu); + virtual bool SetMtu (const uint16_t mtu) = 0; /** * \return the link-level MTU in bytes for this interface. * * This value is typically used by the IP layer to perform * IP fragmentation when needed. */ - uint16_t GetMtu (void) const; - /** - * \param name name of the device (e.g. "eth0") - */ - void SetName(const std::string name); - /** - * \return name name of the device (e.g. "eth0") - */ - std::string GetName(void) const; - /** - * \param index ifIndex of the device - */ - void SetIfIndex(const uint32_t index); - /** - * \return index ifIndex of the device - */ - uint32_t GetIfIndex(void) const; + virtual uint16_t GetMtu (void) const = 0; /** * \return true if link is up; false otherwise */ - bool IsLinkUp (void) const; + virtual bool IsLinkUp (void) const = 0; /** * \param callback the callback to invoke * @@ -117,12 +118,12 @@ * by the IP/ARP layer to flush the ARP cache * whenever the link goes up. */ - void SetLinkChangeCallback (Callback callback); + virtual void SetLinkChangeCallback (Callback callback) = 0; /** * \return true if this interface supports a broadcast address, * false otherwise. */ - bool IsBroadcast (void) const; + virtual bool IsBroadcast (void) const = 0; /** * \return the broadcast address supported by * this netdevice. @@ -130,12 +131,12 @@ * Calling this method is invalid if IsBroadcast returns * not true. */ - Address const &GetBroadcast (void) const; + virtual Address GetBroadcast (void) const = 0; /** * \return value of m_isMulticast flag */ - bool IsMulticast (void) const; + virtual bool IsMulticast (void) const = 0; /** * \brief Return the MAC multicast base address used when mapping multicast @@ -160,8 +161,8 @@ * The method NS_ASSERTs if the device is not a multicast device. * \see NetDevice::MakeMulticastAddress */ - Address GetMulticast (void) const; - + virtual Address GetMulticast (void) const = 0; + /** * \brief Make and return a MAC multicast address using the provided * multicast group @@ -192,12 +193,12 @@ * \see Address * \see NetDevice::IsMulticast */ - virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; - + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const = 0; + /** * \return value of m_isPointToPoint flag */ - bool IsPointToPoint (void) const; + virtual bool IsPointToPoint (void) const = 0; /** * \param packet packet sent from above down to Network Device * \param dest mac address of the destination (already resolved) @@ -210,7 +211,7 @@ * * \return whether the Send operation succeeded */ - bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + virtual bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber) = 0; /** * \returns the node base class which contains this network * interface. @@ -219,7 +220,7 @@ * base class to print the nodeid for example, it can invoke * this method. */ - Ptr GetNode (void) const; + virtual Ptr GetNode (void) const = 0; /** * \returns true if ARP is needed, false otherwise. @@ -227,7 +228,7 @@ * Called by higher-layers to check if this NetDevice requires * ARP to be used. */ - bool NeedsArp (void) const; + virtual bool NeedsArp (void) const = 0; /** * \param device a pointer to the net device which is calling this callback @@ -246,116 +247,10 @@ * be forwarded to the higher layers. * */ - void SetReceiveCallback (ReceiveCallback cb); - - protected: - /** - * \param node base class node pointer of device's node - * \param addr MAC address of this device. - */ - NetDevice(Ptr node, const Address& addr); - /** - * Enable broadcast support. This method should be - * called by subclasses from their constructor - */ - void EnableBroadcast (Address broadcast); - /** - * Set m_isBroadcast flag to false - */ - void DisableBroadcast (void); - /** - * Enable multicast support. This method should be - * called by subclasses from their constructor - */ - void EnableMulticast (Address multicast); - /** - * Set m_isMulticast flag to false - */ - void DisableMulticast (void); - /** - * Set m_isPointToPoint flag to true - */ - void EnablePointToPoint (void); - /** - * Set m_isPointToPoint flag to false - */ - void DisablePointToPoint (void); - /** - * When a subclass notices that the link status has changed to up, - * it notifies its parent class by calling this method. This method - * is responsible for notifying any LinkUp callbacks. - */ - void NotifyLinkUp (void); - /** - * When a subclass notices that the link status has changed to - * down, it notifies its parent class by calling this method. - */ - void NotifyLinkDown (void); + virtual void SetReceiveCallback (ReceiveCallback cb) = 0; - /** - * \param p packet sent from below up to Network Device - * \param param Extra parameter extracted from header and needed by - * some protocols - * \param address the address of the sender of this packet. - * \returns true if the packet was forwarded successfully, - * false otherwise. - * - * When a subclass gets a packet from the channel, it - * forwards it to the higher layers by calling this method - * which is responsible for passing it up to the Rx callback. - */ - bool ForwardUp (Ptr p, uint16_t param, const Address &address); - - - /** - * The dispose method for this NetDevice class. - * Subclasses are expected to override this method _and_ - * to chain up to it by calling NetDevice::DoDispose - * at the end of their own DoDispose method. - */ - virtual void DoDispose (void); - - private: - /** - * \param p packet to send - * \param dest address of destination to which packet must be sent - * \param protocolNumber Number of the protocol (used with some protocols) - * \returns true if the packet could be sent successfully, false - * otherwise. - * - * This is the private virtual target function of the public Send() - * method. When the link is Up, this method is invoked to ask - * subclasses to forward packets. Subclasses MUST override this method. - */ - virtual bool SendTo (Ptr p, const Address &dest, uint16_t protocolNumber) = 0; - /** - * \returns true if this NetDevice needs the higher-layers - * to perform ARP over it, false otherwise. - * - * Subclasses must implement this method. - */ - virtual bool DoNeedsArp (void) const = 0; - /** - * \returns the channel associated to this NetDevice. - * - * Subclasses must implement this method. - */ - virtual Ptr DoGetChannel (void) const = 0; - - Ptr m_node; - std::string m_name; - uint16_t m_ifIndex; - Address m_address; - Address m_broadcast; - Address m_multicast; - uint16_t m_mtu; - bool m_isUp; - bool m_isBroadcast; - bool m_isMulticast; - bool m_isPointToPoint; - Callback m_linkChangeCallback; - ReceiveCallback m_receiveCallback; }; -}; // namespace ns3 -#endif +} // namespace ns3 + +#endif /* NET_DEVICE_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/node-container.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/node/node-container.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,48 @@ +#include "node-container.h" + +namespace ns3 { + +NodeContainer::Iterator +NodeContainer::Begin (void) const +{ + return m_nodes.begin (); +} +NodeContainer::Iterator +NodeContainer::End (void) const +{ + return m_nodes.end (); +} + +uint32_t +NodeContainer::GetN (void) const +{ + return m_nodes.size (); +} +Ptr +NodeContainer::Get (uint32_t i) const +{ + return m_nodes[i]; +} +void +NodeContainer::Create (uint32_t n) +{ + for (uint32_t i = 0; i < n; i++) + { + m_nodes.push_back (CreateObject ()); + } +} +void +NodeContainer::Add (NodeContainer other) +{ + for (Iterator i = other.Begin (); i != other.End (); i++) + { + m_nodes.push_back (*i); + } +} +void +NodeContainer::Add (Ptr node) +{ + m_nodes.push_back (node); +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/node-container.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/node/node-container.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,31 @@ +#ifndef NODE_CONTAINER_H +#define NODE_CONTAINER_H + +#include +#include +#include "node.h" + +namespace ns3 { + +class NodeContainer +{ +public: + typedef std::vector >::const_iterator Iterator; + + Iterator Begin (void) const; + Iterator End (void) const; + + uint32_t GetN (void) const; + Ptr Get (uint32_t i) const; + + void Create (uint32_t n); + void Add (NodeContainer other); + void Add (Ptr node); + + private: + std::vector > m_nodes; +}; + +} // namespace ns3 + +#endif /* NODE_CONTAINER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/node/node-list.cc --- a/src/node/node-list.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/node-list.cc Wed Feb 27 22:19:39 2008 +0100 @@ -22,7 +22,7 @@ #include "ns3/composite-trace-resolver.h" #include "ns3/simulator.h" -#include "ns3/simulation-singleton.h" +#include "ns3/object-vector.h" #include "node-list.h" #include "node.h" @@ -60,9 +60,10 @@ /** * The private node list used by the static-based API */ -class NodeListPriv +class NodeListPriv : public Object { public: + static TypeId GetTypeId (void); NodeListPriv (); ~NodeListPriv (); @@ -73,10 +74,50 @@ Ptr GetNode (uint32_t n); uint32_t GetNNodes (void); + static Ptr Get (void); + private: + static Ptr *DoGet (void); + static void Delete (void); std::vector > m_nodes; }; +TypeId +NodeListPriv::GetTypeId (void) +{ + static TypeId tid = TypeId ("NodeListPriv") + .SetParent () + .AddAttribute ("NodeList", "The list of all nodes created during the simulation.", + ObjectVector (), + MakeObjectVectorAccessor (&NodeListPriv::m_nodes), + MakeObjectVectorChecker ()) + ; + return tid; +} + +Ptr +NodeListPriv::Get (void) +{ + return *DoGet (); +} +Ptr * +NodeListPriv::DoGet (void) +{ + static Ptr ptr = 0; + if (ptr == 0) + { + ptr = CreateObject (); + Simulator::ScheduleDestroy (&NodeListPriv::Delete); + } + return &ptr; +} +void +NodeListPriv::Delete (void) +{ + (*DoGet ()) = 0; +} + + NodeListPriv::NodeListPriv () {} NodeListPriv::~NodeListPriv () @@ -143,42 +184,42 @@ uint32_t NodeList::Add (Ptr node) { - return SimulationSingleton::Get ()->Add (node); + return NodeListPriv::Get ()->Add (node); } NodeList::Iterator NodeList::Begin (void) { - return SimulationSingleton::Get ()->Begin (); + return NodeListPriv::Get ()->Begin (); } NodeList::Iterator NodeList::End (void) { - return SimulationSingleton::Get ()->End (); + return NodeListPriv::Get ()->End (); } Ptr NodeList::GetNode (uint32_t n) { - return SimulationSingleton::Get ()->GetNode (n); + return NodeListPriv::Get ()->GetNode (n); } void NodeList::Connect (std::string name, const CallbackBase &cb) { - SimulationSingleton::Get ()->GetTraceResolver ()->Connect (name, cb, TraceContext ()); + NodeListPriv::Get ()->GetTraceResolver ()->Connect (name, cb, TraceContext ()); } void NodeList::Disconnect (std::string name, const CallbackBase &cb) { - SimulationSingleton::Get ()->GetTraceResolver ()->Disconnect (name, cb); + NodeListPriv::Get ()->GetTraceResolver ()->Disconnect (name, cb); } void NodeList::TraceAll (std::ostream &os) { - SimulationSingleton::Get ()->GetTraceResolver ()->TraceAll (os, TraceContext ()); + NodeListPriv::Get ()->GetTraceResolver ()->TraceAll (os, TraceContext ()); } Ptr NodeList::GetTraceResolver (void) { - return SimulationSingleton::Get ()->GetTraceResolver (); + return NodeListPriv::Get ()->GetTraceResolver (); } }//namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/node/node.cc --- a/src/node/node.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/node.cc Wed Feb 27 22:19:39 2008 +0100 @@ -26,6 +26,8 @@ #include "ns3/packet.h" #include "ns3/simulator.h" #include "ns3/composite-trace-resolver.h" +#include "ns3/object-vector.h" +#include "ns3/uinteger.h" namespace ns3{ @@ -35,68 +37,24 @@ Node::GetTypeId (void) { static TypeId tid = TypeId ("Node") - .SetParent (); + .SetParent () + .AddAttribute ("DeviceList", "The list of devices associated to this Node.", + ObjectVector (), + MakeObjectVectorAccessor (&Node::m_devices), + MakeObjectVectorChecker ()) + .AddAttribute ("ApplicationList", "The list of applications associated to this Node.", + ObjectVector (), + MakeObjectVectorAccessor (&Node::m_applications), + MakeObjectVectorChecker ()) + .AddAttribute ("Id", "The id (unique integer) of this Node.", + TypeId::ATTR_GET, // allow only getting it. + Uinteger (0), + MakeUintegerAccessor (&Node::m_id), + MakeUintegerChecker ()) + ; return tid; } -NodeNetDeviceIndex::NodeNetDeviceIndex () - : m_index (0) -{} -NodeNetDeviceIndex::NodeNetDeviceIndex (uint32_t index) - : m_index (index) -{} -uint32_t -NodeNetDeviceIndex::Get (void) const -{ - return m_index; -} -void -NodeNetDeviceIndex::Print (std::ostream &os) const -{ - os << "device=" << m_index; -} -uint16_t -NodeNetDeviceIndex::GetUid (void) -{ - static uint16_t uid = AllocateUid ("NodeNetDeviceIndex"); - return uid; -} -std::string -NodeNetDeviceIndex::GetTypeName (void) const -{ - return "ns3::NodeNetDeviceIndex"; -} - - -NodeApplicationIndex::NodeApplicationIndex () - : m_index (0) -{} -NodeApplicationIndex::NodeApplicationIndex (uint32_t index) - : m_index (index) -{} -uint32_t -NodeApplicationIndex::Get (void) const -{ - return m_index; -} -void -NodeApplicationIndex::Print (std::ostream &os) const -{ - os << "device=" << m_index; -} -uint16_t -NodeApplicationIndex::GetUid (void) -{ - static uint16_t uid = AllocateUid ("NodeApplicationIndex"); - return uid; -} -std::string -NodeApplicationIndex::GetTypeName (void) const -{ - return "ns3::NodeApplicationIndex"; -} - - Node::Node() : m_id(0), m_sid(0) @@ -122,16 +80,6 @@ Node::~Node () {} -Ptr -Node::GetTraceResolver (void) const -{ - Ptr resolver = Create (); - resolver->AddArray ("devices", m_devices.begin (), m_devices.end (), NodeNetDeviceIndex ()); - resolver->AddArray ("applications", m_applications.begin (), m_applications.end (), NodeApplicationIndex ()); - resolver->SetParentResolver (Object::GetTraceResolver ()); - return resolver; -} - uint32_t Node::GetId (void) const { diff -r d64b1561b1c2 -r e667dc0f350e src/node/node.h --- a/src/node/node.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/node.h Wed Feb 27 22:19:39 2008 +0100 @@ -25,56 +25,16 @@ #include "ns3/object.h" #include "ns3/callback.h" -#include "ns3/trace-context-element.h" #include "ns3/ptr.h" namespace ns3 { class TraceContext; -class TraceResolver; class NetDevice; class Application; class Packet; class Address; -class CompositeTraceResolver; -/** - * \brief hold in a TraceContext the index of a NetDevice within a Node - */ -class NodeNetDeviceIndex : public TraceContextElement -{ -public: - NodeNetDeviceIndex (); - NodeNetDeviceIndex (uint32_t index); - /** - * \returns the index of the NetDevice within its container Node. - */ - uint32_t Get (void) const; - void Print (std::ostream &os) const; - std::string GetTypeName (void) const; - static uint16_t GetUid (void); -private: - uint32_t m_index; -}; - -/** - * \brief hold in a TraceContext the index of an Application within a Node - */ -class NodeApplicationIndex : public TraceContextElement -{ -public: - NodeApplicationIndex (); - NodeApplicationIndex (uint32_t index); - /** - * \returns the index of the Application within its container Node. - */ - uint32_t Get (void) const; - void Print (std::ostream &os) const; - std::string GetTypeName (void) const; - static uint16_t GetUid (void); -private: - uint32_t m_index; -}; /** * \brief A network Node. @@ -199,7 +159,6 @@ void UnregisterProtocolHandler (ProtocolHandler handler); protected: - virtual Ptr GetTraceResolver (void) const; /** * The dispose method. Subclasses must override this method * and must chain up to it by calling Node::DoDispose at the diff -r d64b1561b1c2 -r e667dc0f350e src/node/wscript --- a/src/node/wscript Tue Feb 26 01:39:59 2008 +0100 +++ b/src/node/wscript Wed Feb 27 22:19:39 2008 +0100 @@ -28,6 +28,8 @@ 'tcp.cc', 'ipv4.cc', 'application.cc', + 'node-container.cc', + 'net-device-container.cc', ] headers = bld.create_obj('ns3header') @@ -56,4 +58,6 @@ 'tcp.h', 'ipv4.h', 'application.h', + 'node-container.h', + 'net-device-container.h', ] diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-agent-impl.cc --- a/src/routing/olsr/olsr-agent-impl.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/routing/olsr/olsr-agent-impl.cc Wed Feb 27 22:19:39 2008 +0100 @@ -37,8 +37,9 @@ #include "ns3/log.h" #include "ns3/random-variable.h" #include "ns3/inet-socket-address.h" -#include "ns3/composite-trace-resolver.h" - +#include "ns3/boolean.h" +#include "ns3/uinteger.h" +#include "ns3/trace-source-accessor.h" /********** Useful macros **********/ @@ -153,18 +154,45 @@ TypeId AgentImpl::GetTypeId (void) { - static TypeId tid = TypeId ("OlsrAgentImpl") + static TypeId tid = TypeId ("olsr::AgentImpl") .SetParent () - .AddConstructor > (); + .AddConstructor () + .AddAttribute ("HelloInterval", "XXX", + OLSR_HELLO_INTERVAL, + MakeTimeAccessor (&AgentImpl::m_helloInterval), + MakeTimeChecker ()) + .AddAttribute ("TcInterval", "XXX", + OLSR_TC_INTERVAL, + MakeTimeAccessor (&AgentImpl::m_tcInterval), + MakeTimeChecker ()) + .AddAttribute ("MidInterval", "XXX", + OLSR_MID_INTERVAL, + MakeTimeAccessor (&AgentImpl::m_midInterval), + MakeTimeChecker ()) + .AddAttribute ("Willingness", "XXX", + Uinteger (OLSR_WILL_ALWAYS), + MakeUintegerAccessor (&AgentImpl::m_willingness), + MakeUintegerChecker ()) + .AddTraceSource ("Rx", "Receive OLSR packet.", + MakeTraceSourceAccessor (&AgentImpl::m_rxPacketTrace)) + .AddTraceSource ("Tx", "Send OLSR packet.", + MakeTraceSourceAccessor (&AgentImpl::m_txPacketTrace)) + .AddTraceSource ("RoutingTableChanged", "The OLSR routing table has changed.", + MakeTraceSourceAccessor (&AgentImpl::m_routingTableChanged)) + ; return tid; } -AgentImpl::AgentImpl (Ptr node) +AgentImpl::AgentImpl () : m_helloTimer (Timer::CANCEL_ON_DESTROY), m_tcTimer (Timer::CANCEL_ON_DESTROY), m_midTimer (Timer::CANCEL_ON_DESTROY) +{} + +void +AgentImpl::SetNode (Ptr node) { NS_LOG_DEBUG ("Created olsr::AgentImpl"); m_helloTimer.SetFunction (&AgentImpl::HelloTimerExpire, this); @@ -172,18 +200,10 @@ m_midTimer.SetFunction (&AgentImpl::MidTimerExpire, this); m_queuedMessagesTimer.SetFunction (&AgentImpl::SendQueuedMessages, this); - // Aggregate with the Node, so that OLSR dies when the node is destroyed. - node->AggregateObject (this); - m_packetSequenceNumber = OLSR_MAX_SEQ_NUM; m_messageSequenceNumber = OLSR_MAX_SEQ_NUM; m_ansn = OLSR_MAX_SEQ_NUM; - m_helloInterval = OLSR_HELLO_INTERVAL; - m_tcInterval = OLSR_TC_INTERVAL; - m_midInterval = OLSR_MID_INTERVAL; - m_willingness = OLSR_WILL_ALWAYS; - m_linkTupleTimerFirstTime = true; m_ipv4 = node->GetObject (); @@ -280,32 +300,6 @@ } -Ptr -AgentImpl::GetTraceResolver (void) const -{ - Ptr resolver = Create (); - resolver->AddSource ("rx", - TraceDoc ("receive OLSR packet", - "const olsr::PacketHeader &", "header of OLSR packet received", - "const olsr::MessageList &", "list of OLSR messages contained in the packet" - ), - m_rxPacketTrace); - resolver->AddSource ("tx", - TraceDoc ("send OLSR packet", - "const olsr::PacketHeader &", "header of OLSR packet sent", - "const olsr::MessageList &", "list of OLSR messages contained in the packet" - ), - m_txPacketTrace); - resolver->AddSource ("RoutingTableChanged", - TraceDoc ("the OLSR routing table has changed", - "uint32_t", "size of the new routing table" - ), - m_routingTableChanged); - resolver->SetParentResolver (Object::GetTraceResolver ()); - return resolver; -} - - // // \brief Processes an incoming %OLSR packet following RFC 3626 specification. void diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-agent-impl.h --- a/src/routing/olsr/olsr-agent-impl.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/routing/olsr/olsr-agent-impl.h Wed Feb 27 22:19:39 2008 +0100 @@ -39,7 +39,7 @@ #include "ns3/socket.h" #include "ns3/event-garbage-collector.h" #include "ns3/timer.h" -#include "ns3/callback-trace-source.h" +#include "ns3/traced-callback.h" namespace ns3 { @@ -51,7 +51,9 @@ public: static TypeId GetTypeId (void); - AgentImpl (Ptr node); + AgentImpl (); + + virtual void SetNode (Ptr node); virtual void Start (); virtual void SetMainInterface (uint32_t interface); @@ -87,7 +89,6 @@ protected: void DoDispose (); - Ptr GetTraceResolver (void) const; void SendPacket (Ptr packet, const MessageList &containedMessages); @@ -183,11 +184,11 @@ // HELLO messages arrive) std::map< Ptr, Ipv4Address > m_socketAddresses; - CallbackTraceSource m_rxPacketTrace; - CallbackTraceSource m_txPacketTrace; - CallbackTraceSource m_routingTableChanged; + TracedCallback m_rxPacketTrace; + TracedCallback m_txPacketTrace; + TracedCallback m_routingTableChanged; }; diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-agent.cc --- a/src/routing/olsr/olsr-agent.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/routing/olsr/olsr-agent.cc Wed Feb 27 22:19:39 2008 +0100 @@ -19,17 +19,10 @@ */ #include "olsr-agent.h" -#include "ns3/type-id-default-value.h" namespace ns3 { namespace olsr { -static TypeIdDefaultValue g_defaultImpl = - TypeIdDefaultValue ("OlsrAgentType", - "The type of OlsrAgent implementation", - Agent::GetTypeId (), - "OlsrAgentImpl"); - NS_OBJECT_ENSURE_REGISTERED (Agent); TypeId @@ -40,13 +33,4 @@ return tid; } -Ptr -Agent::CreateDefault (Ptr node) -{ - TypeId tid = g_defaultImpl.GetValue (); - Ptr agent = tid.CreateObject (node)->GetObject (); - return agent; -} - - }} diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-agent.h --- a/src/routing/olsr/olsr-agent.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/routing/olsr/olsr-agent.h Wed Feb 27 22:19:39 2008 +0100 @@ -47,7 +47,7 @@ public: static TypeId GetTypeId (void); - static Ptr CreateDefault (Ptr node); + virtual void SetNode (Ptr node) = 0; /** * \brief Sets the main interface to be used by OLSR @@ -74,7 +74,6 @@ virtual void Start () = 0; }; - }} // namespace olsr, ns3 #endif /* OLSR_AGENT_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-helper.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/routing/olsr/olsr-helper.cc Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,52 @@ +#include "olsr-helper.h" +#include "olsr-agent.h" +#include "ns3/node-list.h" + +namespace ns3 { + +OlsrHelper::OlsrHelper () +{ + m_agentFactory.SetTypeId ("olsr::AgentImpl"); +} + +void +OlsrHelper::SetAgent (std::string tid, + std::string n0, Attribute v0, + std::string n1, Attribute v1, + std::string n2, Attribute v2, + std::string n3, Attribute v3, + std::string n4, Attribute v4, + std::string n5, Attribute v5, + std::string n6, Attribute v6, + std::string n7, Attribute v7) +{ + m_agentFactory.SetTypeId (tid); + m_agentFactory.Set (n0, v0); + m_agentFactory.Set (n1, v1); + m_agentFactory.Set (n2, v2); + m_agentFactory.Set (n3, v3); + m_agentFactory.Set (n4, v4); + m_agentFactory.Set (n5, v5); + m_agentFactory.Set (n6, v6); + m_agentFactory.Set (n7, v7); +} + +void +OlsrHelper::Enable (NodeContainer container) +{ + Enable (container.Begin (), container.End ()); +} +void +OlsrHelper::Enable (Ptr node) +{ + Ptr agent = m_agentFactory.Create (); + agent->SetNode (node); + node->AggregateObject (agent); +} +void +OlsrHelper::EnableAll (void) +{ + Enable (NodeList::Begin (), NodeList::End ()); +} + +} // namespace ns3 diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/olsr-helper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/routing/olsr/olsr-helper.h Wed Feb 27 22:19:39 2008 +0100 @@ -0,0 +1,52 @@ +#ifndef OLSR_HELPER_H +#define OLSR_HELPER_H + +#include "ns3/object-factory.h" +#include "ns3/node-container.h" +#include "ns3/node.h" + +namespace ns3 { + +class OlsrHelper +{ +public: + OlsrHelper (); + + void SetAgent (std::string tid, + std::string n0 = "", Attribute v0 = Attribute (), + std::string n1 = "", Attribute v2 = Attribute (), + std::string n2 = "", Attribute v2 = Attribute (), + std::string n3 = "", Attribute v3 = Attribute (), + std::string n4 = "", Attribute v4 = Attribute (), + std::string n5 = "", Attribute v5 = Attribute (), + std::string n6 = "", Attribute v6 = Attribute (), + std::string n7 = "", Attribute v7 = Attribute ()); + + template + void Enable (InputIterator begin, InputIterator end); + void Enable (NodeContainer container); + void Enable (Ptr node); + void EnableAll (void); +private: + ObjectFactory m_agentFactory; +}; + +} // namespace ns3 + +namespace ns3 { + +template +void +OlsrHelper::Enable (T begin, T end) +{ + for (T i = begin; i != end; i++) + { + Ptr obj = (*i); + Ptr node = obj->GetObject (); + Enable (node); + } +} + +} // namespace ns3 + +#endif /* OLSR_HELPER_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/routing/olsr/wscript --- a/src/routing/olsr/wscript Tue Feb 26 01:39:59 2008 +0100 +++ b/src/routing/olsr/wscript Wed Feb 27 22:19:39 2008 +0100 @@ -9,13 +9,13 @@ 'routing-table.cc', 'olsr-agent.cc', 'olsr-agent-impl.cc', - 'olsr.cc', + 'olsr-helper.cc', ] headers = bld.create_obj('ns3header') headers.source = [ 'olsr-agent.h', - 'olsr.h', 'olsr-header.h', + 'olsr-helper.h', ] diff -r d64b1561b1c2 -r e667dc0f350e src/simulator/event-impl.h --- a/src/simulator/event-impl.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/simulator/event-impl.h Wed Feb 27 22:19:39 2008 +0100 @@ -21,10 +21,12 @@ #define EVENT_IMPL_H #include +#include "ns3/object-base.h" namespace ns3 { -class EventImpl { +class EventImpl : public ObjectBase +{ public: EventImpl (); inline void Ref (void) const; diff -r d64b1561b1c2 -r e667dc0f350e src/simulator/nstime.h --- a/src/simulator/nstime.h Tue Feb 26 01:39:59 2008 +0100 +++ b/src/simulator/nstime.h Wed Feb 27 22:19:39 2008 +0100 @@ -20,9 +20,11 @@ #ifndef TIME_H #define TIME_H +#include "ns3/assert.h" +#include "ns3/attribute.h" +#include "ns3/attribute-helper.h" #include #include -#include "ns3/assert.h" #include #include "high-precision.h" #include "cairo-wideint-private.h" @@ -334,6 +336,8 @@ // additional methods that should not be available for N!=1 // \class TimeUnit<1> +class TimeValue; + template <> class TimeUnit<1> { @@ -431,6 +435,9 @@ static uint64_t UnitsToTimestep (uint64_t unitValue, uint64_t unitFactor); + + TimeUnit (Attribute value); + operator Attribute () const; private: HighPrecision m_data; @@ -513,7 +520,8 @@ typedef TimeUnit<1> Time; -std::ostream& operator<< (std::ostream& os, Time const& time); +std::ostream& operator<< (std::ostream& os, const Time & time); +std::istream& operator>> (std::istream& is, Time & time); /** * \brief create ns3::Time instances in units of seconds. @@ -661,7 +669,10 @@ typedef TimeUnit<-1> TimeInvert; typedef TimeUnit<2> TimeSquare; +ATTRIBUTE_ACCESSOR_DEFINE (Time); +ATTRIBUTE_VALUE_DEFINE (Time); +ATTRIBUTE_CHECKER_DEFINE (Time); -}; // namespace ns3 +} // namespace ns3 #endif /* TIME_H */ diff -r d64b1561b1c2 -r e667dc0f350e src/simulator/simulator.cc --- a/src/simulator/simulator.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/simulator/simulator.cc Wed Feb 27 22:19:39 2008 +0100 @@ -572,7 +572,7 @@ {} -class SimulatorTests : public Test { +class SimulatorTests : public Test, public ObjectBase { public: SimulatorTests (); // only here for testing of Ptr<> diff -r d64b1561b1c2 -r e667dc0f350e src/simulator/time.cc --- a/src/simulator/time.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/src/simulator/time.cc Wed Feb 27 22:19:39 2008 +0100 @@ -22,6 +22,7 @@ #include "nstime.h" #include "ns3/fatal-error.h" #include "ns3/default-value.h" +#include "ns3/object.h" #include namespace ns3 { @@ -188,7 +189,7 @@ std::ostream& -operator<< (std::ostream& os, Time const& time) +operator<< (std::ostream& os, const Time & time) { std::string unit; switch (TimeStepPrecision::Get ()) { @@ -214,6 +215,60 @@ os << time.GetTimeStep () << unit; return os; } +std::istream& operator>> (std::istream& is, Time & time) +{ + std::string value; + is >> value; + std::string::size_type n = value.find_first_not_of("0123456789."); + if (n == std::string::npos) + { + is.setstate (std::ios_base::failbit); + return is; + } + std::string trailer = value.substr(n, value.size ()-1-n); + std::istringstream iss; + iss.str (value.substr(0, n)); + + if (trailer == std::string("s")) + { + double v; + iss >> v; + time = Seconds (v); + return is; + } + uint64_t integer; + iss >> integer; + if (is.bad () || is.fail ()) + { + is.setstate (std::ios_base::failbit); + } + else if (trailer == std::string("ms")) + { + time = MilliSeconds (integer); + } + else if (trailer == std::string("us")) + { + time = MicroSeconds (integer); + } + else if (trailer == std::string("ns")) + { + time = NanoSeconds (integer); + } + else if (trailer == std::string("ps")) + { + time = PicoSeconds (integer); + } + else if (trailer == std::string("fs")) + { + time = FemtoSeconds (integer); + } + else + { + is.setstate (std::ios_base::failbit); + // XXX: problem ? + } + return is; +} Time Seconds (double seconds) { @@ -241,6 +296,23 @@ return unitValue; } +TimeUnit<1>::TimeUnit (Attribute value) +{ + const TimeValue *v = value.DynCast (); + if (v == 0) + { + NS_FATAL_ERROR ("Unexpected type of value. Expected \"TimeValue\""); + } + *this = v->Get (); +} +TimeUnit<1>::operator Attribute () const +{ + return Attribute::Create (*this); +} + +ATTRIBUTE_VALUE_IMPLEMENT (Time); +ATTRIBUTE_CHECKER_IMPLEMENT (Time); + Time MilliSeconds (uint64_t ms) { uint64_t ts = TimeUnit<1>::UnitsToTimestep(ms, TimeStepPrecision::MS_FACTOR); @@ -268,6 +340,8 @@ uint64_t ts = TimeUnit<1>::UnitsToTimestep(fs, TimeStepPrecision::FS_FACTOR); return TimeStep(ts); } + + /* * The timestep value passed to this function must be of the precision * of TimeStepPrecision::Get @@ -287,7 +361,7 @@ return GetHighPrecision ().GetDouble (); } -}; // namespace ns3 +} // namespace ns3 #ifdef RUN_SELF_TESTS diff -r d64b1561b1c2 -r e667dc0f350e tutorial/point-to-point-ipv4-topology.cc --- a/tutorial/point-to-point-ipv4-topology.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/point-to-point-ipv4-topology.cc Wed Feb 27 22:19:39 2008 +0100 @@ -43,8 +43,10 @@ { NS_ASSERT (channel->GetNDevices () <= 1); - Ptr nd = CreateObject (node); - + Ptr nd = + CreateObjectWith ("Node", node, + "Address", Mac48Address::Allocate ()); + node->AddDevice (nd); Ptr q = Queue::CreateDefault (); nd->AddQueue(q); nd->Attach (channel); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-bus-network.cc --- a/tutorial/tutorial-bus-network.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-bus-network.cc Wed Feb 27 22:19:39 2008 +0100 @@ -21,6 +21,8 @@ #include "ns3/simulator.h" #include "ns3/nstime.h" #include "ns3/ascii-trace.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" #include "ipv4-bus-network.h" @@ -41,11 +43,19 @@ uint32_t port = 7; Ptr n0 = bus.GetNode (0); - Ptr client = CreateObject (n0, "10.1.0.1", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.0.1"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); Ptr n1 = bus.GetNode (1); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-csma-echo-ascii-trace.cc --- a/tutorial/tutorial-csma-echo-ascii-trace.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-csma-echo-ascii-trace.cc Wed Feb 27 22:19:39 2008 +0100 @@ -27,6 +27,8 @@ #include "ns3/simulator.h" #include "ns3/nstime.h" #include "ns3/ascii-trace.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); @@ -66,10 +68,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n0, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-csma-echo-pcap-trace.cc --- a/tutorial/tutorial-csma-echo-pcap-trace.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-csma-echo-pcap-trace.cc Wed Feb 27 22:19:39 2008 +0100 @@ -28,6 +28,8 @@ #include "ns3/nstime.h" #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); @@ -67,10 +69,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n0, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-csma-echo.cc --- a/tutorial/tutorial-csma-echo.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-csma-echo.cc Wed Feb 27 22:19:39 2008 +0100 @@ -26,6 +26,8 @@ #include "ns3/udp-echo-server.h" #include "ns3/simulator.h" #include "ns3/nstime.h" +#include "ns3/uinteger.h" +#include "ns3/inet-socket-address.h" NS_LOG_COMPONENT_DEFINE ("UdpEchoSimulation"); @@ -65,10 +67,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n0, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-linear-dumbbell.cc --- a/tutorial/tutorial-linear-dumbbell.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-linear-dumbbell.cc Wed Feb 27 22:19:39 2008 +0100 @@ -32,6 +32,8 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/global-route-manager.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" NS_LOG_COMPONENT_DEFINE ("DumbbellSimulation"); @@ -124,19 +126,55 @@ // uint16_t port = 7; - Ptr client0 = CreateObject (n0, "10.1.2.1", - port, 100, Seconds(.01), 1024); - Ptr client1 = CreateObject (n1, "10.1.2.2", - port, 100, Seconds(.01), 1024); - Ptr client2 = CreateObject (n2, "10.1.2.3", - port, 100, Seconds(.01), 1024); - Ptr client3 = CreateObject (n3, "10.1.2.4", - port, 100, Seconds(.01), 1024); + Ptr client0 = + CreateObjectWith ( + "Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.2.1"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (100), + "Interval", Seconds (0.01), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client0); + Ptr client1 = + CreateObjectWith ( + "Node", n1, + "RemoteIpv4", Ipv4Address ("10.1.2.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (100), + "Interval", Seconds (0.01), + "PacketSize", Uinteger (1024)); + n1->AddApplication (client1); + Ptr client2 = + CreateObjectWith ( + "Node", n2, + "RemoteIpv4", Ipv4Address ("10.1.2.3"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (100), + "Interval", Seconds (0.01), + "PacketSize", Uinteger (1024)); + n2->AddApplication (client2); + Ptr client3 = + CreateObjectWith ( + "Node", n3, + "RemoteIpv4", Ipv4Address ("10.1.2.4"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (100), + "Interval", Seconds (0.01), + "PacketSize", Uinteger (1024)); + n3->AddApplication (client3); - Ptr server4 = CreateObject (n4, port); - Ptr server5 = CreateObject (n5, port); - Ptr server6 = CreateObject (n6, port); - Ptr server7 = CreateObject (n7, port); + Ptr server4 = + CreateObjectWith ("Node", n4, "Port", Uinteger (port)); + n4->AddApplication (server4); + Ptr server5 = + CreateObjectWith ("Node", n5, "Port", Uinteger (port)); + n5->AddApplication (server5); + Ptr server6 = + CreateObjectWith ("Node", n6, "Port", Uinteger (port)); + n6->AddApplication (server6); + Ptr server7 = + CreateObjectWith ("Node", n7, "Port", Uinteger (port)); + n7->AddApplication (server7); server4->Start(Seconds(1.)); server5->Start(Seconds(1.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-point-to-point.cc --- a/tutorial/tutorial-point-to-point.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-point-to-point.cc Wed Feb 27 22:19:39 2008 +0100 @@ -28,6 +28,8 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/global-route-manager.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation"); @@ -58,10 +60,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n0, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-star-routing.cc --- a/tutorial/tutorial-star-routing.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-star-routing.cc Wed Feb 27 22:19:39 2008 +0100 @@ -27,6 +27,8 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/global-route-manager.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" #include "point-to-point-ipv4-topology.h" @@ -145,10 +147,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n4, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n4, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e tutorial/tutorial-star.cc --- a/tutorial/tutorial-star.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/tutorial/tutorial-star.cc Wed Feb 27 22:19:39 2008 +0100 @@ -27,6 +27,8 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/global-route-manager.h" +#include "ns3/inet-socket-address.h" +#include "ns3/uinteger.h" #include "point-to-point-ipv4-topology.h" @@ -145,10 +147,19 @@ uint16_t port = 7; - Ptr client = CreateObject (n0, "10.1.1.2", - port, 1, Seconds(1.), 1024); + Ptr client = + CreateObjectWith ("Node", n0, + "RemoteIpv4", Ipv4Address ("10.1.1.2"), + "RemotePort", Uinteger (port), + "MaxPackets", Uinteger (1), + "Interval", Seconds(1.), + "PacketSize", Uinteger (1024)); + n0->AddApplication (client); - Ptr server = CreateObject (n1, port); + Ptr server = + CreateObjectWith ("Node", n1, + "Port", Uinteger (port)); + n1->AddApplication (server); server->Start(Seconds(1.)); client->Start(Seconds(2.)); diff -r d64b1561b1c2 -r e667dc0f350e utils/mobility-visualizer-model.cc --- a/utils/mobility-visualizer-model.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/utils/mobility-visualizer-model.cc Wed Feb 27 22:19:39 2008 +0100 @@ -5,7 +5,7 @@ #include "ns3/ptr.h" #include "ns3/mobility-model.h" #include "ns3/mobility-model-notifier.h" -#include "ns3/random-topology.h" +#include "ns3/position-allocator.h" #include "ns3/default-value.h" #include "ns3/command-line.h" #include "ns3/command-line.h" @@ -15,6 +15,7 @@ #include "ns3/node-list.h" #include "ns3/rectangle-default-value.h" #include "ns3/type-id-default-value.h" +#include "ns3/mobility-helper.h" #include "mobility-visualizer.h" @@ -89,20 +90,21 @@ CommandLine::Parse (argc, argv); - RandomTopology topology; + MobilityHelper mobility; for (uint32_t i = 0; i < g_numNodes; i++) { Ptr node = CreateObject (); - node->AggregateObject (CreateObject ()); } - topology.Layout (NodeList::Begin (), NodeList::End ()); + mobility.EnableNotifier (); + mobility.Layout (NodeList::Begin (), NodeList::End ()); Simulator::Schedule (g_sampleInterval, Sample); - TypeId mobType = DefaultValueListGet ("RandomTopologyMobilityType")->GetValue (); - if (mobType.GetName () == "RandomWalkMobilityModel") + // XXX: The following is not really going to work with the params. + + if (mobility.GetMobilityModelType () == "RandomWalk2dMobilityModel") { Rectangle bounds = DefaultValueListGet ("RandomWalk2dBounds")->GetValue (); *x1 = bounds.xMin; @@ -112,7 +114,7 @@ std::cout << "RECT " << bounds.xMin << " " << bounds.xMax << " " << bounds.yMin << " " << bounds.yMax << std::endl; } - else if (mobType.GetName () == "RandomDirection2dMobilityModel") + else if (mobility.GetMobilityModelType () == "RandomDirection2dMobilityModel") { Rectangle bounds = DefaultValueListGet ("RandomDirection2dArea")->GetValue (); *x1 = bounds.xMin; @@ -122,7 +124,7 @@ std::cout << "RECT " << bounds.xMin << " " << bounds.xMax << " " << bounds.yMin << " " << bounds.yMax << std::endl; } - else if (mobType.GetName () == "RandomWaypointMobilityModel") + else if (mobility.GetMobilityModelType () == "RandomWaypointMobilityModel") { std::cerr << "bounds for RandomWaypointMobilityModel not implemented" << std::endl; //ClassId posType = DefaultValueList::Get ("RandomWaypointPosition")->GetValue (); @@ -130,7 +132,7 @@ } else { - NS_FATAL_ERROR ("mobility type " << mobType.GetName () << " not supported"); + NS_FATAL_ERROR ("mobility type " << mobility.GetMobilityModelType () << " not supported"); } std::cerr << g_sampleInterval << std::endl; diff -r d64b1561b1c2 -r e667dc0f350e utils/print-introspected-doxygen.cc --- a/utils/print-introspected-doxygen.cc Tue Feb 26 01:39:59 2008 +0100 +++ b/utils/print-introspected-doxygen.cc Wed Feb 27 22:19:39 2008 +0100 @@ -7,6 +7,7 @@ #include "ns3/queue.h" #include "ns3/mobility-model-notifier.h" #include "ns3/default-value.h" +#include "ns3/string.h" using namespace ns3; @@ -119,9 +120,14 @@ Ptr node = CreateObject (); node->AggregateObject (CreateObject ()); - Ptr p2p = CreateObject (node); + Ptr p2p = CreateObjectWith ("Node", node, + "Address", Mac48Address::Allocate ()); + node->AddDevice (p2p); p2p->AddQueue (Queue::CreateDefault ()); - Ptr csma = CreateObject (node); + Ptr csma = CreateObjectWith ("Node", node, + "Address", Mac48Address::Allocate (), + "EncapsulationMode", String ("Llc")); + node->AddDevice (csma); csma->AddQueue (Queue::CreateDefault ()); TraceResolver::SourceCollection collection;