merge
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Sun, 28 Dec 2008 12:34:28 +0000
changeset 4034 ca0ea1ed6fc8
parent 4033 6abf5a0f12d7 (current diff)
parent 4032 2b675a0b3b94 (diff)
child 4035 749cf964666a
child 4065 f18c257dd25e
merge
src/helper/yans-wifi-phy-helper.cc
src/helper/yans-wifi-phy-helper.h
--- a/.hgignore	Sun Dec 07 19:02:55 2008 +0000
+++ b/.hgignore	Sun Dec 28 12:34:28 2008 +0000
@@ -11,6 +11,7 @@
 ^doc/introspected-doxygen\.h$
 .*\.py[co]$
 \.pcap$
+\.mob$
 ^doc/manual/manual/
 doc/manual/manual.aux
 doc/manual/manual.cp
--- a/.hgtags	Sun Dec 07 19:02:55 2008 +0000
+++ b/.hgtags	Sun Dec 28 12:34:28 2008 +0000
@@ -26,3 +26,8 @@
 0000000000000000000000000000000000000000 ns-3.3-RC1
 a84f2ab246e691a88b527a84ce21896b95080070 ns-3.3-RC1
 654eed5f3ad03c04c2bcfb6852b5b4ae94260bc6 ns-3.3-RC2
+a66553c56a8f14644af6c229c83bb0a653cb3f32 ns-3.3-RC3
+dfd0bc16dc991313896f351530a3dc5a25f62e15 ns-3.3-RC4
+58ae52c5845ff03ba08dc921e13e6cf3604c810a ns-3.3-RC5
+4267fd454004f5a60e517496f43a01000ccebc72 ns-3.3-RC6
+2efae18e73794c0acd8061a9bd5c74b69f1b0d93 ns-3.3
--- a/AUTHORS	Sun Dec 07 19:02:55 2008 +0000
+++ b/AUTHORS	Sun Dec 28 12:34:28 2008 +0000
@@ -13,4 +13,5 @@
 David Gross (gdavid.devel@gmail.com)
 Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
 Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
+Luis Cortes (cortes@gatech.edu)
 
--- a/bindings/python/ns3_module_helper.py	Sun Dec 07 19:02:55 2008 +0000
+++ b/bindings/python/ns3_module_helper.py	Sun Dec 28 12:34:28 2008 +0000
@@ -47,9 +47,9 @@
     module.add_class('WifiHelper', allow_subclassing=False)
     ## wifi-helper.h: ns3::WifiPhyHelper [class]
     module.add_class('WifiPhyHelper', allow_subclassing=False)
-    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper [class]
+    ## yans-wifi-helper.h: ns3::YansWifiChannelHelper [class]
     module.add_class('YansWifiChannelHelper', allow_subclassing=False)
-    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper [class]
+    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
     module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
     
     ## Register a nested module for the namespace Config
@@ -879,24 +879,24 @@
     return
 
 def register_Ns3YansWifiChannelHelper_methods(root_module, cls):
-    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper(ns3::YansWifiChannelHelper const & arg0) [copy constructor]
+    ## yans-wifi-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper(ns3::YansWifiChannelHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::YansWifiChannelHelper const &', 'arg0')])
-    ## yans-wifi-phy-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper() [constructor]
+    ## yans-wifi-helper.h: ns3::YansWifiChannelHelper::YansWifiChannelHelper() [constructor]
     cls.add_constructor([])
-    ## yans-wifi-phy-helper.h: static ns3::YansWifiChannelHelper ns3::YansWifiChannelHelper::Default() [member function]
+    ## yans-wifi-helper.h: static ns3::YansWifiChannelHelper ns3::YansWifiChannelHelper::Default() [member function]
     cls.add_method('Default', 
                    'ns3::YansWifiChannelHelper', 
                    [], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: void ns3::YansWifiChannelHelper::AddPropagationLoss(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
+    ## yans-wifi-helper.h: void ns3::YansWifiChannelHelper::AddPropagationLoss(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
     cls.add_method('AddPropagationLoss', 
                    'void', 
                    [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## yans-wifi-phy-helper.h: void ns3::YansWifiChannelHelper::SetPropagationDelay(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
+    ## yans-wifi-helper.h: void ns3::YansWifiChannelHelper::SetPropagationDelay(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
     cls.add_method('SetPropagationDelay', 
                    'void', 
                    [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## yans-wifi-phy-helper.h: ns3::Ptr<ns3::YansWifiChannel> ns3::YansWifiChannelHelper::Create() const [member function]
+    ## yans-wifi-helper.h: ns3::Ptr<ns3::YansWifiChannel> ns3::YansWifiChannelHelper::Create() const [member function]
     cls.add_method('Create', 
                    'ns3::Ptr< ns3::YansWifiChannel >', 
                    [], 
@@ -904,72 +904,72 @@
     return
 
 def register_Ns3YansWifiPhyHelper_methods(root_module, cls):
-    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper(ns3::YansWifiPhyHelper const & arg0) [copy constructor]
+    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper(ns3::YansWifiPhyHelper const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::YansWifiPhyHelper const &', 'arg0')])
-    ## yans-wifi-phy-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper() [constructor]
+    ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::YansWifiPhyHelper() [constructor]
     cls.add_constructor([])
-    ## yans-wifi-phy-helper.h: static ns3::YansWifiPhyHelper ns3::YansWifiPhyHelper::Default() [member function]
+    ## yans-wifi-helper.h: static ns3::YansWifiPhyHelper ns3::YansWifiPhyHelper::Default() [member function]
     cls.add_method('Default', 
                    'ns3::YansWifiPhyHelper', 
                    [], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::SetChannel(ns3::Ptr<ns3::YansWifiChannel> channel) [member function]
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetChannel(ns3::Ptr<ns3::YansWifiChannel> channel) [member function]
     cls.add_method('SetChannel', 
                    'void', 
                    [param('ns3::Ptr< ns3::YansWifiChannel >', 'channel')])
-    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::Set(std::string name, ns3::AttributeValue const & v) [member function]
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::Set(std::string name, ns3::AttributeValue const & v) [member function]
     cls.add_method('Set', 
                    'void', 
                    [param('std::string', 'name'), param('ns3::AttributeValue const &', 'v')])
-    ## yans-wifi-phy-helper.h: void ns3::YansWifiPhyHelper::SetErrorRateModel(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
+    ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetErrorRateModel(std::string name, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function]
     cls.add_method('SetErrorRateModel', 
                    'void', 
                    [param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
-    ## yans-wifi-phy-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::YansWifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
-    cls.add_method('Create', 
-                   'ns3::Ptr< ns3::WifiPhy >', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
-                   is_const=True, is_virtual=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
                    [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
     cls.add_method('EnablePcapAll', 
                    'void', 
                    [param('std::string', 'filename')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('ns3::NetDeviceContainer', 'd')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, ns3::NodeContainer n) [member function]
     cls.add_method('EnableAscii', 
                    'void', 
                    [param('std::ostream &', 'os'), param('ns3::NodeContainer', 'n')], 
                    is_static=True)
-    ## yans-wifi-phy-helper.h: static void ns3::YansWifiPhyHelper::EnableAsciiAll(std::ostream & os) [member function]
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAsciiAll(std::ostream & os) [member function]
     cls.add_method('EnableAsciiAll', 
                    'void', 
                    [param('std::ostream &', 'os')], 
                    is_static=True)
+    ## yans-wifi-helper.h: ns3::Ptr<ns3::WifiPhy> ns3::YansWifiPhyHelper::Create(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::WifiNetDevice> device) const [member function]
+    cls.add_method('Create', 
+                   'ns3::Ptr< ns3::WifiPhy >', 
+                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::WifiNetDevice >', 'device')], 
+                   is_const=True, visibility='private', is_virtual=True)
     return
 
 def register_functions(root_module):
--- a/bindings/python/ns3_module_simulator.py	Sun Dec 07 19:02:55 2008 +0000
+++ b/bindings/python/ns3_module_simulator.py	Sun Dec 28 12:34:28 2008 +0000
@@ -764,11 +764,6 @@
                    'void', 
                    [], 
                    is_pure_virtual=True, is_virtual=True)
-    ## simulator-impl.h: void ns3::SimulatorImpl::Stop(ns3::Time const & time) [member function]
-    cls.add_method('Stop', 
-                   'void', 
-                   [param('ns3::Time const &', 'time')], 
-                   is_pure_virtual=True, is_virtual=True)
     ## simulator-impl.h: ns3::EventId ns3::SimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
     cls.add_method('Schedule', 
                    'ns3::EventId', 
@@ -1101,11 +1096,6 @@
                    'void', 
                    [], 
                    is_virtual=True)
-    ## default-simulator-impl.h: void ns3::DefaultSimulatorImpl::Stop(ns3::Time const & time) [member function]
-    cls.add_method('Stop', 
-                   'void', 
-                   [param('ns3::Time const &', 'time')], 
-                   is_virtual=True)
     ## default-simulator-impl.h: ns3::EventId ns3::DefaultSimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
     cls.add_method('Schedule', 
                    'ns3::EventId', 
@@ -1299,11 +1289,6 @@
                    'void', 
                    [], 
                    is_virtual=True)
-    ## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::Stop(ns3::Time const & time) [member function]
-    cls.add_method('Stop', 
-                   'void', 
-                   [param('ns3::Time const &', 'time')], 
-                   is_virtual=True)
     ## realtime-simulator-impl.h: ns3::EventId ns3::RealtimeSimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
     cls.add_method('Schedule', 
                    'ns3::EventId', 
--- a/doc/manual/Makefile	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/Makefile	Sun Dec 28 12:34:28 2008 +0000
@@ -17,7 +17,8 @@
 	$(FIGURES)/buffer.eps \
 	$(FIGURES)/sockets-overview.eps \
 	$(FIGURES)/testbed.eps \
-	$(FIGURES)/emulated-channel.eps
+	$(FIGURES)/emulated-channel.eps \
+	$(FIGURES)/snir.eps
 
 IMAGES_PNG = ${IMAGES_EPS:.eps=.png}
 IMAGES_PDF = ${IMAGES_EPS:.eps=.pdf}
@@ -28,18 +29,21 @@
 	manual.texi \
 	attributes.texi \
 	callbacks.texi \
+	csma.texi \
 	emulation.texi \
 	node.texi \
 	objects.texi \
 	other.texi \
 	output.texi \
 	packets.texi \
+	point-to-point.texi \
 	random.texi \
 	realtime.texi \
 	routing.texi \
 	sockets.texi \
 	statistics.texi \
-	troubleshoot.texi
+	troubleshoot.texi \
+	wifi.texi
 
 %.eps : %.dia; $(DIA) -t eps $< -e $@
 %.png : %.dia; $(DIA) -t png $< -e $@
--- a/doc/manual/attributes.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/attributes.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -713,7 +713,7 @@
 
 @subsection Future work
 There are a couple of possible improvements:
-@itemize bullet
+@itemize @bullet
 @item save a unique version number with date and time at start of file
 @item save rng initial seed somewhere.
 @item make each RandomVariable serialize its own initial seed and re-read
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/csma.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,334 @@
+@node CSMA NetDevice
+@chapter CSMA NetDevice
+
+This is the introduction to CSMA NetDevice chapter, to complement the
+Csma model doxygen.
+
+@menu
+* Overview of the model::
+* Using the CsmaNetDevice::
+* CSMA Tracing::
+@end menu
+
+@node Overview of the model
+@section Overview of the model
+
+The ns-3 CSMA device models a simple bus network in the spirit of Ethernet.
+Although it does not model any real physical network you could ever build 
+or buy, it does provide some very useful functionality.
+
+Typically when one thinks of a bus network Ethernet or IEEE 802.3 comes to
+mind.  Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision
+Detection with exponentially increasing backoff to contend for the shared 
+transmission medium.  The ns-3 CSMA device models only a portion of this 
+process, using the nature of the globally available channel to provide 
+instantaneous (faster than light) carrier sense and priority-based 
+collision "avoidance."  Collisions in the sense of Ethernet never happen and
+so the ns-3 CSMA device does not model collision detection, nor will any
+transmission in progress be "jammed."
+
+@subsection CSMA Layer Model
+
+There are a number of conventions in use for describing layered 
+communications architectures in the literature and in textbooks.  The most
+common layering  model is the ISO seven layer reference model.  In this view
+the CsmaNetDevice and CsmaChannel pair occupies the lowest two 
+layers -- at the physical (layer one), and data link (layer two) positions.
+Another important reference model is that specified by RFC 1122, 
+"Requirements for Internet Hosts -- Communication Layers."  In this view the
+CsmaNetDevice and CsmaChannel pair occupies the lowest layer -- 
+the link layer.  There is also a seemingly endless litany of alternative 
+descriptions found in textbooks and in the literature.  We adopt the naming
+conventions used in the IEEE 802 standards which speak of LLC, MAC, MII
+and PHY layering.  These acronyms are defined as:
+
+@itemize @bullet
+@item LLC:  Logical Link Control;
+@item MAC:  Media Access Control;
+@item MII:  Media Independent Interface;
+@item PHY:  Physical Layer.
+@end itemize
+
+In this case the @emph{LLC} and @emph{MAC }are sublayers of the OSI data link 
+layer and the @emph{MII} and @emph{PHY} are sublayers of the OSI physical layer.
+
+The "top" of the CSMA device defines the transition from the network layer
+to the data link layer.  This transition is performed by higher layers by 
+calling either CsmaNetDevice::Send or CsmaNetDevice::SendFrom.
+
+In contrast to the IEEE 802.3 standards, there is no precisely specified
+PHY in the CSMA model in the sense of wire types, signals or pinouts.  The
+"bottom" interface of the CsmaNetDevice can be thought of as as a kind
+of Media Independent Interface (MII) as seen in the "Fast Ethernet" 
+(IEEE 802.3u) specifications.  This MII interface fits into a corresponding
+media independent interface on the CsmaChannel.  You will not find the
+equivalent of a 10BASE-T or a 1000BASE-LX PHY.
+
+The CsmaNetDevice calls the CsmaChannel through a media independent
+interface.  There is a method defined to tell the channel when to start 
+"wiggling the wires" using the method CsmaChannel::TransmitStart, and 
+a method to tell the channel when the transmission process is done and
+the channel should begin propagating the last bit across the "wire":
+CsmaChannel::TransmitEnd.
+
+When the TransmitEnd method is executed, the channel will model a single 
+uniform signal propagation delay in the medium and deliver copes of the packet
+to each of the devices attached to the packet via the 
+CsmaNetDevice::Receive method.
+
+There is a "pin" in the device media independent interface corresponding to 
+"COL" (collision).  The state of the channel may be sensed by calling 
+CsmaChannel::GetState.  Each device will look at this "pin" before 
+starting a send and will perform appropriate backoff operations if required.
+
+Properly received packets are forwarded up to higher levels from the 
+CsmaNetDevice via a callback mechanism.  The callback function is
+initialized by the higher layer (when the net device is attached) using
+CsmaNetDevice::SetReceiveCallback and is invoked upon "proper"
+ reception of a packet by the net device in order to forward the packet up
+the protocol stack.
+
+@section CSMA Channel Model
+
+The class CsmaChannel models the actual transmission medium.
+There is no fixed limit for the number of devices connected to the channel.
+The CsmaChannel models a data rate and a speed-of-light delay which can
+be accessed via the attributes "DataRate" and "Delay" respectively.
+The data rate provided to the channel is used to set the data rates
+used by the transmitter sections of the CSMA devices connected to the 
+channel.  There is no way to independently set data rates in the
+devices.  Since the data rate is only used to calculate a delay time, there
+is no limitation (other than by the data type holding the value) on the 
+speed at which CSMA channels and devices can operate; and no restriction
+based on any kind of PHY characteristics.
+
+The CsmaChannel has three states, @code{IDLE}, @code{TRANSMITTING} and 
+@code{PROPAGATING}.  These three states are "seen" instantaneously by all 
+devices on the channel.  By this we mean that if one device begins or ends a
+simulated transmission, all devices on the channel are @emph{immediately}
+aware of the change in state.  There is no time during which one device may
+see an @code{IDLE} channel while another device physically further away in 
+the collision domain may have begun transmitting with the associated signals 
+not propagated down the channel to other devices.  Thus there is no need for
+collision detection in the CsmaChannel model and it is not implemented in any
+way.
+
+We do, as the name indicates, have a Carrier Sense aspect to the model.
+Since the simulator is single threaded, access to the common channel will
+be serialized by the simulator.  This provides a deterministic mechanism
+for contending for the channel.  The channel is allocated (transitioned from
+state @code{IDLE} to state @code{TRANSMITTING}) on a first-come first-served 
+basis.  The channel always goes through a three state process:
+
+@verbatim
+  IDLE -> TRANSMITTING -> PROPAGATING -> IDLE
+@end verbatim
+
+The @code{TRANSMITTING} state models the time during which the source net device
+is actually wiggling the signals on the wire.  The @code{PROPAGATING} state 
+models the time after the last bit was sent, when the signal is propagating down 
+the wire to the "far end."  
+
+The transition to the @code{TRANSMITTING} state is  driven by a call to 
+CsmaChannel::TransmitStart which is called by the net device that 
+transmits the packet.  It is the responsibility of that device to end the
+transmission with a call to CsmaChannel::TransmitEnd at the appropriate
+simulation time that reflects the time elapsed to put all of the packet bits
+on the wire.  When TransmitEnd is called, the channel schedules an event
+corresponding to a single speed-of-light delay.  This delay applies to all
+net devices on the channel identically.  You can think of a symmetrical hub
+in which the packet bits propagate to a central location and then back out
+equal length cables to the other devices on the channel.  The single ``speed
+of light'' delay then corresponds to the time it takes for: 1) a singal to 
+propagate from one CsmaNetDevice through its cable to the hub; plus 2) the
+time it takes for the hub to forward the packet out a port; plus 3) the time
+it takes for the signal in question to propagate to the destination net 
+device.
+
+The CsmaChannel models a broadcast medium so the packet is delivered
+to all of the devices on the channel (including the source) at the end of 
+the propagation time.  It is the responsibility of the sending device to 
+determine whether or not it receives a packet broadcast over the channel.
+
+The CsmaChannel provides following Attributes:
+
+@itemize @bullet
+@item DataRate:  The bitrate for packet transmission on connected devices;
+@item Delay: The speed of light transmission delay for the channel.
+@end itemize
+
+@section CSMA Net Device Model
+
+ The CSMA network device appears somewhat like an Ethernet device.  The
+ CsmaNetDevice provides following Attributes:
+
+@itemize @bullet
+@item Address:  The Mac48Address of the device;
+@item SendEnable:  Enable packet transmission if true;
+@item ReceiveEnable:  Enable packet reception if true;
+@item EncapsulationMode:  Type of link layer encapsulation to use;
+@item RxErrorModel:  The receive error model;
+@item TxQueue:  The trasmit queue used by the device;
+@item InterframeGap:  The optional time to wait between "frames";
+@item Rx:  A trace source for received packets;
+@item Drop:  A trace source for dropped packets.
+@end itemize
+
+The CsmaNetDevice supports the assignment of a "receive error model."
+This is an ErrorModel object that is used to simulate data corruption
+on the link.
+
+Packets sent over the CsmaNetDevice are always routed through the 
+transmit queue to provide a trace hook for packets sent out over the 
+network.  This transmit queue can be set (via attribute) to model different
+queueing strategies.
+
+Also configurable by attribute is the encapsulation method used by the
+device.  Every packet gets an EthernetHeader that includes the 
+destination and source MAC addresses, and a length/type field.  Every packet
+also gets an EthernetTrailer which includes the FCS.  Data in the
+packet may be encapsulated in different ways.  
+
+By default, or by setting the "EncapsulationMode" attribute to "Dix", the 
+encapsulation is according to the DEC, Intel, Xerox standard.  This is sometimes
+called EthernetII framing and is the familiar destination MAC, source MAC, 
+EtherType, Data, CRC format.
+
+If the "EncapsulationMode" attribute is set to "Llc", the encapsulation is by 
+LLC SNAP.  In this case, a SNAP header is added that contains the EtherType
+(IP or ARP).  
+
+The other implemented encapsulation modes are IP_ARP (set "EncapsulationMode" to
+"IpArp") in which the length type of the Ethernet header receives the protocol 
+number of the packet; or ETHERNET_V1 (set "EncapsulationMode" to "EthernetV1") 
+in which the length type of the Ethernet header receives the length of the packet.
+A "Raw" encapsulation mode is defined but not implemented -- use of the RAW mode 
+results in an assertion.  
+
+Note that all net devices on a channel must be set to the same encapsulation mode
+for correct results.  The encapsulation mode is not sensed at the receiver.
+
+The CsmaNetDevice implements a random exponential backoff algorithm 
+that is executed if the channel is determined to be busy (@code{TRANSMITTING} or
+@code{PPROPAGATING}) when the device wants to start propagating.  This results in a
+random delay of up to pow (2, retries) - 1 microseconds before a retry is
+attempted.  The default maximum number of retries is 1000.
+
+@node Using the CsmaNetDevice
+@section Using the CsmaNetDevice
+
+The CSMA net devices and channels are typically created and configured using
+the associated @code{CsmaHelper} object.  The various ns3 device dhelpers 
+generatlly work in a simlar way, and their use is seen in many of our example
+programs.
+
+The conceptual model of interest is that of a bare computer ``husk'' into which 
+you plug net devices.  The bare computers are created using a @code{NodeContainer}
+helper.  You just ask this helper to create as many computers (we call them
+@code{Nodes}) as you need on your network:
+
+@verbatim
+  NodeContainer csmaNodes;
+  csmaNodes.Create (nCsmaNodes);
+@end verbatim
+
+Once you have your nodes, you need to instantiate a @code{CsmaHelper} and set
+any attributes you may want to change.
+
+@verbatim
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
+
+  csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Dix"));
+  csma.SetDeviceAttribute ("FrameSize", UintegerValue (2000));
+@end verbatim
+ 
+Once the attributes are set, all that remains is to create the devices
+and install them on the required nodes, and to connect the devices 
+together using a CSMA channel.  When we create the net devices, we add
+them to a container to allow you to use them in the future.  This all
+takes just one line of code.
+
+@verbatim
+  NetDeviceContainer csmaDevices = csma.Install (csmaNodes);
+@end verbatim
+
+@node Csma Tracing
+@section CSMA Tracing
+
+Like all ns-3 devices, the CSMA Model provides a number of trace sources.
+These trace sources can be hooked using your own custom trace code, or you
+can use our helper functions to arrange for tracing to be enabled on devices
+you specify.
+
+@subsection Upper-Level (MAC) Hooks
+
+From the point of view of tracing in the net device, there are several 
+interesting points to insert trace hooks.  A convention inherited from other
+simulators is that packets destined for transmission onto attached networks
+pass through a single "transmit queue" in the net device.  We provide trace 
+hooks at this point in packet flow, which corresponds (abstractly) only to a 
+transition from the network to data link layer, and call them collectively
+the device MAC hooks.
+
+When a packet is sent to the CSMA net device for transmission it always 
+passes through the transmit queue.  The transmit queue in the 
+CsmaNetDevice inherits from Queue, and therefore inherits three 
+trace sources:
+
+@itemize @bullet
+@item An Enqueue operation source (see Queue::m_traceEnqueue);
+@item A Dequeue operation source (see Queue::m_traceDequeue);
+@item A Drop operation source (see Queue::m_traceDrop).
+@end itemize
+
+The upper-level (MAC) trace hooks for the CsmaNetDevice are, in fact, 
+exactly these three trace sources on the single transmit queue of the device.  
+
+The m_traceEnqueue event is triggered when a packet is placed on the transmit
+queue.  This happens at the time that CsmaNetDevice::Send or 
+CsmaNetDevice::SendFrom is called by a higher layer to queue a packet for 
+transmission.
+
+The m_traceDequeue event is triggered when a packet is removed from the
+transmit queue.  Dequeues from the transmit queue can happen in three 
+situations:  1) If the underlying channel is idle when the 
+CsmaNetDevice::Send or CsmaNetDevice::SendFrom is called, a packet
+is dequeued from the transmit queue and immediately transmitted;  2) If the
+underlying channel is idle, a packet may be dequeued and immediately 
+transmitted in an internal TransmitCompleteEvent that functions much 
+like a transmit complete interrupt service routine; or 3) from
+the random exponential backoff handler if a timeout is detected.
+
+Case (3) implies that a packet is dequeued from the transmit queue if it is 
+unable to be transmittted according to the backoff rules.  It is important 
+to understand that this will appear as a Dequeued packet and it is easy to 
+incorrectly assume that the packet was transmitted since it passed through
+the transmit queue.  In fact, a packet is actually dropped by the net device
+in this case.  The reason for this behavior is due to the definition of the 
+Queue Drop event.  The m_traceDrop event is, by defintion, fired when a 
+packet cannot be enqueued on the transmit queue becasue it is full.  This 
+event only fires if the queue is full and we do not overload this event
+to indicate that the CsmaChannel is "full."
+
+@subsection Lower-Level (PHY) Hooks
+
+Similar to the upper level trace hooks, there are trace hooks available at
+the lower levels of the net device.  We call these the PHY hooks.  These 
+events fire from the device methods that talk directly to the CsmaChannel.
+
+The trace source m_dropTrace is called to indicate a packet that is dropped
+by the device.  This happens in two cases:  First, if the receive side of 
+the net device is not enabled (see CsmaNetDevice::m_receiveEnable and the 
+associated attribute "ReceiveEnable").
+
+The m_dropTrace is also used to indicate that a packet was discarded as 
+corrupt if a receive error model is used (see 
+CsmaNetDevice::m_receiveErrorModel and the associated attribute 
+"ReceiveErrorModel").
+
+The other low-level trace source fires on reception of an accepted packet
+(see CsmaNetDevice::m_rxTrace).  A packet is accepted if it is destined
+for the broadcast address, a multicast address, or to the MAC address 
+assigned to the net device.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/emu.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,183 @@
+@node Emu NetDevice
+@chapter Emu NetDevice
+
+This is the introduction to Emu NetDevice chapter, to complement the
+Emu model doxygen.
+
+@menu
+* Overview of the model::
+* Using the EmuNetDevice::
+* Emu Tracing::
+@end menu
+
+@node Overview of the model
+@section Overview of the model
+
+The emulated net device allows a simulation node to send and receive packets
+a real network.
+
+The Emu net device is not a complete net device and channel combination as is
+typical in ns-3.  The Emu device can be thought of as a proxy for a real
+device that resides in an ns-3 simulation.  The Emu net device talks to that
+real device using raw sockets and binds to the device via the Linux interface.
+There is no related Emu channel since other devices will most likely reside on
+different computers running entirely separate simulations.
+
+The Emu net device relies on a specified interface (``eth1, for example) being
+in promiscuous mode.  It opens a raw socket and binds to that interface.  We 
+perform MAC spoofing to separate simulation network traffic from other network
+traffic that may be flowing to and from the host.
+
+Normally, the use case for emulated net devices is in collections of
+small simulations that connect to the outside world through specific 
+interfaces.  For example, one could construct a number of virtual
+machines and connect them via a host-only network.  To use the emulated
+net device, you would need to set all of the host-only interfaces in
+promiscuous mode and provide an appropriate device name, "eth1" for example.
+
+One could also use the emulated net device in a testbed situation
+where the host on which the simulation is running has a specific interface
+of interest which drives the testbed hardware.  You would also need to set 
+this specific interface into promiscuous mode and provide an appropriate 
+device name to the ns-3 emulated net device.
+
+The emulated net device only works if the underlying interface is up in 
+promiscuous mode.  We could just turn it on, but the situation is that we 
+expect the other considerations listed above to have been dealt with.
+To verify that these issues are dealt with, we just make sure that the end 
+result of that process has taken place and that the specified interface is
+in promiscuous mode.
+
+@subsection Address Concerns
+
+Packets will be sent out over the device, but as mentioned, we use MAC spoofing.
+By default in the simulation, the MAC addresses will be generated using the 
+Organizationally Unique Identifier (OUI) 00:00:00 as a base.  This vendor code
+is not assigned to any organization and so should not conflict with any real 
+hardware.  
+
+It is always up to you to determine that using these MAC addresses is
+okay on your network and won't conflict with anything else (including another
+simulation using emu devices) on your network.  If you are using the 
+emulated net device in separate simulations you must consider global MAC 
+address assignment issues and ensure that MAC addresses are unique across
+all simulations.  The emulated net device respects the MAC address provided
+in the SetAddress method so you can do this manually.  For larger simulations,
+you may want to set the OUI in the MAC address allocation function.
+
+IP addresses corresponding to the emulated net devices are the addresses 
+generated in the simulation, which are generated in the usual way via helper
+functions.
+
+@subsection Attributes
+
+The Emu network device appears to the ns-3 system just as any other device and
+can be controlled through the attribute system, and traced through conventional
+trace hooks.  The EmuNetDevice provides following Attributes:
+
+@itemize @bullet
+@item Address:  The Mac48Address of the device;
+@item DeviceName: The name of the underlying real device (e.g., ``eth1'');
+@item Start:  The simualtion time at which to enable the underlying socket;
+@item Stop:  The simualtion time at which to stop receiving from the underlying socket;
+@item TxQueue:  The trasmit queue used by the device;
+@item InterframeGap:  The optional time to wait between "frames";
+@item Rx:  A trace source for received packets;
+@end itemize
+
+Packets sent over the EmuNetDevice are always routed through the 
+transmit queue to provide a trace hook for packets sent out over the 
+network.  This transmit queue can be set (via attribute) to model different
+queueing strategies.
+
+@node Using the EmuNetDevice
+@section Using the EmuNetDevice
+
+The emulated net device comes with a helper function as all ns-3 devices do.
+One unique aspect is that there is no channel associated with the underlying
+medium.  We really have no idea what this medium is, and so have not made an
+effort to model it abstractly.  The primary thing to be aware of is the 
+implication this has for static global routing.  The global router module
+attempts to walk the channels looking for adjacent networks.  Since there 
+is no channel, the global router will be unable to do this.
+
+The Emu net devices are typically created and configured using the associated 
+@code{EmuHelper} object.  The various ns3 device helpers generatlly work in a
+simlar way, and their use is seen in many of our example programs.
+
+The conceptual model of interest is that of a bare computer ``husk'' into which 
+you plug net devices.  The bare computers are created using a @code{NodeContainer}
+helper.  You just ask this helper to create as many computers (we call them
+@code{Nodes}) as you need on your network:
+
+@verbatim
+  NodeContainer nodes;
+  nodes.Create (nEmuNodes);
+@end verbatim
+
+Once you have your nodes, you need to instantiate a @code{EmuHelper} and set
+any attributes you may want to change.
+
+@verbatim
+  EmuHelper emu;
+  csma.SetAttribute ("DeviceName", StringValue ("eth1"));
+@end verbatim
+ 
+Once the attributes are set, all that remains is to create the devices
+and install them on the required nodes.  When we create the net devices, 
+we add them to a container to allow you to use them in the future.  This 
+all takes just one line of code.
+
+@verbatim
+  NetDeviceContainer emuDevices = emu.Install (nodes);
+@end verbatim
+
+@node Emu Tracing
+@section Emu Tracing
+
+Like all ns-3 devices, the Emu Model provides a number of trace sources.
+These trace sources can be hooked using your own custom trace code, or you
+can use our helper functions to arrange for tracing to be enabled on devices
+you specify.
+
+@subsection Upper-Level (MAC) Hooks
+
+From the point of view of tracing in the net device, there are several 
+interesting points to insert trace hooks.  A convention inherited from other
+simulators is that packets destined for transmission onto attached networks
+pass through a single "transmit queue" in the net device.  We provide trace 
+hooks at this point in packet flow, which corresponds (abstractly) only to a 
+transition from the network to data link layer, and call them collectively
+the device MAC hooks.
+
+When a packet is sent to the Emu net device for transmission it always 
+passes through the transmit queue.  The transmit queue in the 
+EmuNetDevice inherits from Queue, and therefore inherits three 
+trace sources:
+
+@itemize @bullet
+@item An Enqueue operation source (see Queue::m_traceEnqueue);
+@item A Dequeue operation source (see Queue::m_traceDequeue);
+@item A Drop operation source (see Queue::m_traceDrop).
+@end itemize
+
+The upper-level (MAC) trace hooks for the EmuNetDevice are, in fact, 
+exactly these three trace sources on the single transmit queue of the device.  
+
+The m_traceEnqueue event is triggered when a packet is placed on the transmit
+queue.  This happens at the time that EmuNetDevice::Send or 
+EmuNetDevice::SendFrom is called by a higher layer to queue a packet for 
+transmission.
+
+The m_traceDequeue event is triggered when a packet is removed from the
+transmit queue.  Dequeues from the transmit queue happen immediately after
+the Enqueue event and just prior to the packet being sent to the underlying
+socket.  This means that the transmit queue really only exists to fire on
+enqueue and dequeue operations so the Emu device bhaves like other ns-3
+devices in this repect.
+
+@subsection Lower-Level (PHY) Hooks
+
+There are no lower level trace hooks implemented in the Emu net device since
+we rely on the underlying OS implementation of the raw socket to perform
+the low level operations required to send and receive packets.
Binary file doc/manual/figures/snir.dia has changed
--- a/doc/manual/manual.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/manual.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -89,6 +89,9 @@
 * Node and Internet Stack::
 * TCP::
 * Routing overview::
+* Wifi NetDevice::
+* CSMA NetDevice::
+* PointToPoint NetDevice::
 * Troubleshooting::
 @end menu
 
@@ -104,6 +107,9 @@
 @c @include output.texi
 @include tcp.texi
 @include routing.texi
+@include wifi.texi
+@include csma.texi
+@include point-to-point.texi
 @c @include other.texi
 @include troubleshoot.texi
 
--- a/doc/manual/node.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/node.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -204,7 +204,7 @@
 
 First, note that the @code{Receive ()} function has a matching signature
 to the ReceiveCallback in the @code{class Node}.  This function pointer
-is inserted into the the Node's protocol handler when 
+is inserted into the Node's protocol handler when 
 @code{AddInterface ()} is called.  The actual registration is done
 with a statement such as:
 follows:
--- a/doc/manual/objects.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/objects.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -48,7 +48,7 @@
 @node Object base classes
 @section Object base classes
 
-There are two special base classes used in ns-3.  Classes that inherit
+There are three special base classes used in ns-3.  Classes that inherit
 from these base classes can instantiate objects with special properties.
 These base classes are:
 @itemize @bullet
@@ -61,8 +61,8 @@
 @code{class Object} get the following properties.
 @itemize @bullet
 @item the ns-3 type and attribute system (see @ref{Attributes})
+@item an object aggregation system
 @item a smart-pointer reference counting system (class Ptr)
-@item an object aggregation system
 @end itemize
 
 Classes that derive from @code{class ObjectBase} get the first two
@@ -106,9 +106,6 @@
 non-reference-counted objects on the heap, using operator new, 
 are responsible for deleting such objects.
 
-Packet objects are handled differently (without reference
-counting); their design is described in @ref{Packets}.
-
 @subsection Reference counting smart pointer (Ptr)
 
 Calling @code{Ref()} and @code{Unref()} all the time would be cumbersome,
@@ -145,12 +142,15 @@
 @verbatim
  Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
 @end verbatim
+Please do not create such objects using @code{operator new}; create them
+using @code{CreateObject()} instead.
 
 For objects deriving from @code{class RefCountBase}, or other
-objects that support usage of smart pointer (e.g., the ns-3 Packet class),
+objects that support usage of the smart pointer class
+(in particular, the ns-3 Packet class),
 a templated helper function is available and recommended to be used:
 @verbatim
-  ns3::Ptr<B> b = ns3::Create<B> ();
+  Ptr<B> b = Create<B> ();
 @end verbatim  
 This is simply a wrapper around operator new that correctly handles
 the reference counting system.
@@ -207,15 +207,20 @@
 Then, they are aggregated to the node.  In this manner, the Node base
 class does not need to be edited to allow users with a base class Node
 pointer to access the Ipv4 interface; users may ask the node for a pointer
-to its Ipv4 interface at runtime.  How this is done is seen in the next
-subsection.
+to its Ipv4 interface at runtime.  How the user asks the node is described
+in the next subsection.
+
+Note that it is a programming error to aggregate more than one object of
+the same type to an ns3::Object.  So, for instance, aggregation is not
+an option for storing all of the active sockets of a node.
 
 @subsubsection GetObject example
 GetObject is a type-safe way to achieve a safe downcasting 
 and to allow interfaces to be found on an object.  
 
 Consider a node pointer @code{m_node} that points to a Node object 
-with an implementation of IPv4.  The client code wishes to configure
+that has an implementation of IPv4 previously aggregated to it.  The 
+client code wishes to configure
 a default route.  To do so, it must access an object within
 the node that has an interface to the IP forwarding configuration.
 It performs the following:
@@ -229,28 +234,18 @@
 now use the Ptr to the Ipv4 object that was previously aggregated to
 the node.
 
-@subsubsection Summary
-To summarize, two benefits that we expect to leverage from this are as follows:
-@itemize @bullet
-@item @strong{Encapsulation:} By separating interface from implementation, 
-it permits
-implementors to replace elements of the protocol stack while remaining
-compliant with client code that supports the same interface.  For
-example, one type of node may include native ns-3 models of protocols,
-while another may be a port of a Linux stack, and both may be accessed
-by the same base class node pointer.
-@item @strong{Aggregation:} AggregateObject allows for aggregation of 
-objects at
-run time.  For instance, an existing Node object may have an ``Energy Model''
+Another example of how one might use aggregation is to add optional
+models to objects.  For in
+For instance, an existing Node object may have an ``Energy Model''
 object aggregated to it at run time (without modifying
 and recompiling the node class).  An existing model (such as a wireless
 net device) can then later "GetObject" for the energy model and act 
 appropriately if the interface has been either built in to the underlying
-Node object or aggregated to it at run time.
-@end itemize
+Node object or aggregated to it at run time.  However, other nodes need
+not know anything about energy models.
 
 We hope that this mode of programming will require much less 
-need for developers to modify the @code base classes or libraries.
+need for developers to modify the base classes.
 
 @node Downcasting
 @section Downcasting
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/point-to-point.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,177 @@
+@node PointToPoint NetDevice
+@chapter PointToPoint NetDevice
+
+This is the introduction to PointToPoint NetDevice chapter, to complement the
+PointToPoint model doxygen.
+
+@menu
+* Overview of the model::
+* Using the PointToPointNetDevice::
+* PointToPoint Tracing::
+@end menu
+
+@node Overview of the model
+@section Overview of the model
+
+The ns-3 point-to-point model is of a very simple point to point data link
+connecting exactly two PointToPointNetDevice devices over an
+PointToPointChannel.  This can be viewed as equivalent to a full
+duplex RS-232 or RS-422 link with null modem and no handshaking.
+
+Data is encapsulated in the Point-to-Point Protocol (PPP -- RFC 1661),
+however the Link Control Protocol (LCP) and associated state machine is 
+not implemented.  The PPP link is assumed to be established and 
+authenticated at all times.
+
+Data is not framed, therefore Address and Control fields will not be found.
+Since the data is not framed, there is no need to provide Flag Sequence and
+Control Escape octets, nor is a Frame Check Sequence appended.  All that is
+required to implement non-framed PPP is to prepend the PPP protocol number
+for IP Version 4 which is the sixteen-bit number 0x21 (see
+http://www.iana.org/assignments/ppp-numbers).
+
+The PointToPointNetDevice provides following Attributes:
+
+@itemize @bullet
+@item Address:  The ns3::Mac48Address of the device (if desired);
+@item DataRate:  The data rate (ns3::DataRate) of the device;
+@item TxQueue:  The trasmit queue (ns3::Queue) used by the device;
+@item InterframeGap:  The optional ns3::Time to wait between "frames";
+@item Rx:  A trace source for received packets;
+@item Drop:  A trace source for dropped packets.
+@end itemize
+
+The PointToPointNetDevice models a transmitter section that puts bits
+on a corresponding channel "wire."  `The DataRate attribute specifies the
+number of bits per second that the device will simulate sending over the 
+channel.  In reality no bits are sent, but an event is scheduled for an
+elapsed time consistent with the number of bits in each packet and the 
+specified DataRate.  The implication here is that the receiving device
+models a receiver section that can receive any any data rate.  Therefore
+there is no need, nor way to set a receive data rate in this model.  By
+setting the DataRate on the transmitter of both devices connected to a 
+given PointToPointChannel one can model a symmetric channel; or by 
+setting different DataRates one can model an asymmetric channel (e.g., 
+ADSL).
+
+The PointToPointNetDevice supports the assignment of a "receive error 
+model."  This is an ErrorModel object that is used to simulate data
+corruption on the link.
+
+@section  Point-to-Point Channel Model
+
+The point to point net devices are connected via an 
+PointToPointChannel.  This channel models two wires transmitting bits
+at the data rate specified by the source net device.  There is no overhead
+beyond the eight bits per byte of the packet sent.  That is, we do not 
+model Flag Sequences, Frame Check Sequences nor do we "escape" any data.
+
+The PointToPointChannel provides following Attributes:
+
+@itemize @bullet
+@item Delay:  An ns3::Time specifying the speed of light transmission delay for
+the channel.
+@end itemize
+
+@node Using the PointToPointNetDevice
+@section Using the PointToPointNetDevice
+
+The PointToPoint net devices and channels are typically created and configured using
+the associated @code{PointToPointHelper} object.  The various ns3 device helpers 
+generally work in a simlar way, and their use is seen in many of our example
+programs and is also covered in the ns-3 tutorial.
+
+The conceptual model of interest is that of a bare computer ``husk'' into which 
+you plug net devices.  The bare computers are created using a @code{NodeContainer}
+helper.  You just ask this helper to create as many computers (we call them
+@code{Nodes}) as you need on your network:
+
+@verbatim
+  NodeContainer nodes;
+  nodes.Create (2);
+@end verbatim
+
+Once you have your nodes, you need to instantiate a @code{PointToPointHelper} and set
+any attributes you may want to change.  Note that since this is a point-to-point 
+(as compared to a point-to-mulipoint) there may only be two nodes with associated 
+net devices connected by a PointToPointChannel.
+
+@verbatim
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+@end verbatim
+ 
+Once the attributes are set, all that remains is to create the devices
+and install them on the required nodes, and to connect the devices 
+together using a PointToPoint channel.  When we create the net devices, we add
+them to a container to allow you to use them in the future.  This all
+takes just one line of code.
+
+@verbatim
+  NetDeviceContainer devices = pointToPoint.Install (nodes);
+@end verbatim
+
+@node PointToPoint Tracing
+@section PointToPoint Tracing
+
+Like all ns-3 devices, the Point-to-Point Model provides a number of trace 
+sources.  These trace sources can be hooked using your own custom trace code,
+or you can use our helper functions to arrange for tracing to be enabled on 
+devices you specify.
+
+@subsection Upper-Level (MAC) Hooks
+
+From the point of view of tracing in the net device, there are several 
+interesting points to insert trace hooks.  A convention inherited from other
+simulators is that packets destined for transmission onto attached networks
+pass through a single "transmit queue" in the net device.  We provide trace 
+hooks at this point in packet flow, which corresponds (abstractly) only to a 
+transition from the network to data link layer, and call them collectively
+the device MAC hooks.
+
+When a packet is sent to the Point-to-Point net device for transmission it 
+always passes through the transmit queue.  The transmit queue in the 
+PointToPointNetDevice inherits from Queue, and therefore inherits three 
+trace sources:
+
+@itemize @bullet
+@item An Enqueue operation source (see ns3::Queue::m_traceEnqueue);
+@item A Dequeue operation source (see ns3::Queue::m_traceDequeue);
+@item A Drop operation source (see ns3::Queue::m_traceDrop).
+@end itemize
+
+The upper-level (MAC) trace hooks for the PointToPointNetDevice are, in fact, 
+exactly these three trace sources on the single transmit queue of the device.  
+
+The m_traceEnqueue event is triggered when a packet is placed on the transmit
+queue.  This happens at the time that ns3::PointtoPointNetDevice::Send or 
+ns3::PointToPointNetDevice::SendFrom is called by a higher layer to queue a 
+packet for transmission.  An Enqueue trace event firing should be interpreted
+as only indicating that a higher level protocol has sent a packet to the device.
+
+The m_traceDequeue event is triggered when a packet is removed from the
+transmit queue.  Dequeues from the transmit queue can happen in two
+situations:  1) If the underlying channel is idle when 
+PointToPointNetDevice::Send is called, a packet is dequeued from the transmit
+queue and immediately transmitted;  2) a packet may be dequeued and 
+immediately transmitted in an internal TransmitCompleteEvent that functions 
+much  like a transmit complete interrupt service routine.  An Dequeue trace 
+event firing may be viewed as indicating that the PointToPointNetDevice has
+begun transmitting a packet.
+
+@subsection Lower-Level (PHY) Hooks
+
+Similar to the upper level trace hooks, there are trace hooks available at
+the lower levels of the net device.  We call these the PHY hooks.  These 
+events fire from the device methods that talk directly to the 
+PointToPointChannel.
+
+The trace source m_dropTrace is called to indicate a packet that is dropped
+by the device.  This happens when a packet is discarded as corrupt due to a 
+receive error model indication (see ns3::ErrorModel and the associated 
+attribute "ReceiveErrorModel").
+
+The other low-level trace source fires on reception of a packet (see 
+ns3::PointToPointNetDevice::m_rxTrace) from the PointToPointChannel.
--- a/doc/manual/routing.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/routing.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -301,6 +301,20 @@
 @emph{Note:} A reminder that the wifi NetDevice is not yet supported
 (only CSMA and PointToPoint).
 
+It is possible to call this function again in the midst of a simulation
+using the following additional public function:
+@verbatim
+  GlobalRouteManager::RecomputeRoutingTables ();
+@end verbatim
+which flushes the old tables, queries the nodes for new interface information,
+and rebuilds the routes.
+
+For instance, this scheduling call will cause the tables to be rebuilt
+at time 5 seconds:
+@verbatim
+  Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
+@end verbatim
+
 @node Global Routing Implementation
 @section Global Routing Implementation
 
--- a/doc/manual/sockets.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/manual/sockets.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -194,7 +194,7 @@
 @section POSIX-like sockets API 
 
 @emph{this capability is under development and is scheduled for
-inclusion in August 2008 timeframe; see the repository
+inclusion in the ns-3.5 releasetimeframe; see the repository
 http://code.nsnam.org/mathieu/ns-3-simu for details}
 
 The below is excerpted from Mathieu's post to ns-developers list
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/wifi.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,359 @@
+@node Wifi NetDevice
+@chapter Wifi NetDevice
+@anchor{chap:wifi}
+
+ns-3 nodes can contain a collection of NetDevice objects, much like an actual 
+computer contains separate interface cards for Ethernet, Wifi, Bluetooth, etc.  This chapter describes the ns-3 WifiNetDevice and related models.  By
+adding WifiNetDevice objects to ns-3 nodes, one can create models of
+802.11-based infrastructure and ad hoc networks.
+
+@menu
+* Overview of the model::
+* Using the WifiNetDevice::
+* The WifiChannel and WifiPhy models::
+* The MAC model::
+* Wifi Attributes::
+* Wifi Tracing::
+@end menu
+
+@node Overview of the model
+@section Overview of the model
+
+@strong{Note:}  This overview is taken largely from the Doxygen for the
+WifiNetDevice module.
+
+The set of 802.11 models provided in ns-3 attempts to provide
+an accurate MAC-level implementation of the 802.11 specification
+and to provide a not-so-slow PHY-level model of the 802.11a
+specification.
+
+The current implementation provides roughly four levels of models:
+@itemize @bullet
+@item the @strong{PHY layer models}
+@item the so-called @strong{MAC low models}: they implement DCF
+@item the so-called @strong{MAC high models}: they implement the MAC-level
+beacon generation, probing, and association state machines, and
+@item a set of @strong{Rate control algorithms} used by the MAC low models
+@end itemize
+
+There are presently three @strong{MAC high models}:
+@enumerate
+@item a simple adhoc state machine that does not perform any
+kind of beacon generation, probing, or association. This
+state machine is implemented by the @code{ns3::AdhocWifiNetDevice}
+and @code{ns3::MacHighAdhoc} classes.
+@item  an active probing and association state machine that handles
+automatic re-association whenever too many beacons are missed
+is implemented by the @code{ns3::NqstaWifiNetDevice} and
+@code{ns3::MacHighNqsta} classes.
+@item an access point that generates periodic beacons, and that
+accepts every attempt to associate. This AP state machine
+is implemented by the @code{ns3::NqapWifiNetDevice} and
+@code{ns3::MacHighNqap} classes.
+@end enumerate 
+
+The @strong{MAC low layer} is split into three components:
+@enumerate
+@item @code{ns3::MacLow} which takes care of RTS/CTS/DATA/ACK transactions.
+@item @code{ns3::DcfManager} and @code{ns3::DcfState} which implements the DCF function.
+@item @code{ns3::DcaTxop} which handles the packet queue, packet fragmentation,
+and packet retransmissions if they are needed.
+@end enumerate
+
+There are also several @strong{rate control algorithms} that can be used by the Mac low layer:
+@itemize @bullet
+@item @code{ns3::ArfMacStations}
+@item @code{ns3::AArfMacStations}
+@item @code{ns3::IdealMacStations}
+@item @code{ns3::CrMacStations}
+@item @code{ns3::OnoeMacStations}
+@item @code{ns3::AmrrMacStations}
+@end itemize
+
+The PHY layer implements a single model in the 
+@code{ns3::WifiPhy class}: the
+physical layer model implemented there is described fully in a paper 
+entitled @uref{http://cutebugs.net/files/wns2-yans.pdf,,"Yet Another Network Simulator"}. 
+
+In ns-3, nodes can have multiple WifiNetDevices on separate channels,
+and the WifiNetDevice can coexist with other device types; this removes
+an architectural limitation found in ns-2.  Presently, however, there
+is no model for cross-channel interference or coupling.
+
+The source code for the Wifi NetDevice lives in the directory
+@code{src/devices/wifi}.
+
+@node Using the WifiNetDevice
+@section Using the WifiNetDevice
+
+Users who use the low-level ns-3 API and who wish to add a WifiNetDevice
+to their node must create an instance of a WifiNetDevice, plus 
+a number of consitutent objects, and bind them together appropriately
+(the WifiNetDevice is very modular in this regard, for future
+extensibility).  At the low-level API, this can be done
+with about 20 lines of code (see @code{ns3::WifiHelper::Install} and
+@code{ns3::YansWifiPhyHelper::Create}).  They also must create,
+at some point, a WifiChannel, which also contains a number of
+constituent objects (see @code{ns3::YansWifiChannelHelper::Create}).
+
+However, a few helpers are available for users to add these devices
+and channels with only a few lines of code, if they are willing to
+use defaults, and the helpers provide additional API to allow the
+passing of attribute values to change default values.  The scripts
+in @code{src/examples} can be browsed to see how this is done.
+
+@subsection YansWifiChannelHelper
+
+The YansWifiChannelHelper has an unusual name.  Readers may wonder why
+it is named this way.  The reference is to the 
+@uref{http://cutebugs.net/files/wns2-yans.pdf,,yans simulator},
+from which this model is taken.  The helper can be used to create
+a WifiChannel with a default PropagationLoss and PropagationDelay model.  
+Specifically, the default is a channel model
+with a propagation delay equal to a constant, the speed of light,
+and a propagation loss based on a log distance model with a reference 
+loss of 46.6777 dB at reference distance of 1m.
+
+Users will typically type code such as:
+@verbatim
+  YansWifiChannelHelper wifiChannelHelper = YansWifiChannelHelper::Default ();
+  Ptr<WifiChannel> wifiChannel = wifiChannelHelper.Create ();
+@end verbatim
+to get the defaults.  Note the distinction above in creating a helper
+object vs. an actual simulation object.
+In ns-3, helper objects (used at the helper API only) are created on the
+stack (they could also be created with operator new and later deleted).
+However, the actual ns-3 objects typically inherit from 
+@code{class ns3::Object} and are assigned to a smart pointer.  See the
+chapter on 
+@uref{Object model} for a discussion of the ns-3 object model, if you
+are not familiar with it.
+
+@emph{Todo:  Add notes about how to configure attributes with this helper API}
+
+@subsection YansWifiPhyHelper
+
+Physical devices (base class @code{ns3::Phy}) connect to 
+@code{ns3::Channel} models in ns-3.  We need to create Phy objects appropriate
+for the YansWifiChannel; here the @code{YansWifiPhyHelper} will
+do the work.
+
+The YansWifiPhyHelper class configures an object factory to create instances
+of a @code{YansWifiPhy} and
+adds some other objects to it, including possibly a supplemental 
+ErrorRateModel and a pointer to a MobilityModel.  The user code is
+typically:
+@verbatim
+  YansWifiPhyHelper wifiPhyHelper = YansWifiPhyHelper::Default ();
+  wifiPhyHelper.SetChannel (wifiChannel);
+@end verbatim
+Note that we haven't actually created any WifiPhy objects yet; we've 
+just prepared the YansWifiPhyHelper by telling it which channel it is 
+connected to.  The phy objects are created in the next step.
+
+@subsection WifiHelper
+
+We're now ready to create WifiNetDevices.  First, let's create
+a WifiHelper with default settings:
+@verbatim
+  WifiHelper wifiHelper = WifiHelper::Default ();
+@end verbatim
+What does this do?  It sets the RemoteStationManager to
+@code{ns3::ArfWifiManager} and the upper MAC to @code{ns3::AdhocWifiMac}
+by default (which can be overridden by other arguments).
+Now, let's use the wifiPhyHelper created above to install WifiNetDevices
+on a set of nodes in a NodeContainer "c":
+@verbatim
+  NetDeviceContainer wifiContainer = WifiHelper::Install (wifiPhyHelper, c);
+@end verbatim
+This creates the WifiNetDevice which includes also a WifiRemoteStationManager,
+a WifiMac, and a WifiPhy (connected to the matching WifiChannel).
+
+There are many ns-3 @uref{Attributes} that can be set on the above
+helpers to deviate from the default behavior; the example scripts
+show how to do some of this reconfiguration.
+
+@subsection AdHoc WifiNetDevice configuration 
+This is a typical example of how a user might configure an adhoc network.
+
+@emph{Write me}
+
+@subsection Infrastructure (Access Point and clients) WifiNetDevice configuration 
+This is a typical example of how a user might configure an access point and a set of clients. 
+
+@emph{Write me}
+
+@node The WifiChannel and WifiPhy models
+@section The WifiChannel and WifiPhy models
+
+The WifiChannel subclass can be used to connect together a set of
+@code{ns3::WifiNetDevice} network interfaces. The class @code{ns3::WifiPhy}
+is the
+object within the WifiNetDevice that receives bits from the channel.
+A WifiChannel contains
+a @code{ns3::PropagationLossModel} and a @code{ns3::PropagationDelayModel} 
+which can
+be overridden by the WifiChannel::SetPropagationLossModel
+and the WifiChannel::SetPropagationDelayModel methods. By default,
+no propagation models are set.
+
+The WifiPhy models an 802.11a channel, in terms of frequency, modulation,
+and bit rates, and interacts with the PropagationLossModel and 
+PropagationDelayModel found in the channel.  
+
+This section summarizes
+the description of the BER calculations found in the yans paper
+taking into account the
+Forward Error Correction present in 802.11a and describes
+the algorithm we implemented to decide whether or not a 
+packet can be successfully received.  See @uref{http://cutebugs.net/files/wns2-yans.pdf,,"Yet Another Network Simulator"} for more details.
+
+The PHY layer can be in one of three states:
+@enumerate
+@item TX: the PHY is currently transmitting a signal
+on behalf of its associated MAC
+@item RX: the PHY is synchronized on a signal and
+is waiting until it has received its last bit to forward
+it to the MAC.
+@item IDLE: the PHY is not in the TX or RX states.
+@end enumerate
+
+When the first bit of a new packet is received while
+the PHY is not IDLE (that is, it is already synchronized
+on the reception of another earlier packet or it is
+sending data itself), the received packet is dropped. 
+Otherwise, if the PHY is IDLE, we calculate the received
+energy of the first bit of this new signal and compare it 
+against our Energy Detection threshold (as defined 
+by the Clear Channel Assessment function mode 1). 
+If the energy of the packet k is higher, then the PHY moves 
+to RX state and schedules an event when the last bit of 
+the packet is expected to be received. Otherwise, the 
+PHY stays in IDLE state and drops the packet.
+
+The energy of the received signal is assumed
+to be zero outside of the reception interval of packet k and
+is calculated from the transmission power with a path-loss 
+propagation model in the reception interval.
+where the path loss exponent, @math{n}, is chosen equal to 3, 
+the reference distance, @math{d_0} is choosen equal to 
+@math{1.0m} and 
+the reference energy is based based on a Friis
+propagation model.
+
+When the last bit of the packet upon which the PHY is 
+synchronized is received, we need to calculate the 
+probability that the packet is received with any error
+to decide whether or not 
+the packet on which we were synchronized could
+be successfully received or not: a random number 
+is drawn from a uniform distribution and is compared against
+the probability of error.
+
+To evaluate the probability of error, we start from the piecewise linear 
+functions shown in Figure @ref{fig:snir} and calculate the 
+SNIR function. 
+
+@float Figure,fig:snir
+@caption{SNIR function over time}
+@image{figures/snir,,3in} 
+@end float 
+
+From the SNIR function we can derive bit error rates for BPSK and QAM
+modulations.  Then, for each interval l where BER is
+constant, we define the upper bound of a probability that an error is
+present in the chunk of bits located in the interval l for packet k.
+If we assume an AWGN channel, 
+binary convolutional coding (which is the case in 802.11a)
+and hard-decision Viterbi decoding, the error rate is thus derived,
+and the packet error probability for packet k can be computed.. 
+
+@subsection WifiChannel configuration
+
+WifiChannel models include both a PropagationDelayModel and a 
+PropagationLossModel.  The following PropagationDelayModels are available:
+@itemize @bullet
+@item ConstantSpeedPropagationDelayModel
+@item RandomPropagationDelayModel
+@end itemize
+
+The following PropagationLossModels are available:
+@itemize @bullet
+@item RandomPropagationLossModel
+@item FriisPropagationLossModel
+@item LogDistancePropagationLossModel
+@item JakesPropagationLossModel
+@item CompositePropagationLossModel
+@end itemize
+
+@node The MAC model
+@section The MAC model
+
+The 802.11 Distributed Coordination Function is used to
+calculate when to grant access to the transmission medium. While
+implementing the DCF would have been particularly easy if we
+had used a recurring timer that expired every slot, we
+chose to use the method described in @emph{(missing reference here from
+Yans paper)}
+where the backoff timer duration is lazily calculated whenever
+needed since it is claimed to have much better performance than
+the simpler recurring timer solution.
+
+The higher-level MAC functions are implemented in a set of other
+C++ classes and deal with:
+@itemize @bullet
+@item packet fragmentation and defragmentation,
+@item use of the rts/cts protocol,
+@item rate control algorithm,
+@item connection and disconnection to and from an Access Point,
+@item the MAC transmission queue,
+@item beacon generation,
+@item etc.
+@end itemize
+
+@node Wifi Attributes
+@section Wifi Attributes
+
+The WifiNetDevice makes heavy use of the ns-3 @ref{Attributes} subsystem for
+configuration and default value management.  Presently, approximately
+100 values are stored in this system.
+
+For instance, class @code{ns-3::WifiMac} exports these attributes:
+@itemize @bullet
+@item CtsTimeout: When this timeout expires, the RTS/CTS handshake has failed.
+@item AckTimeout: When this timeout expires, the DATA/ACK handshake has failed.
+@item Sifs: The value of the SIFS constant.
+@item EifsNoDifs: The value of EIFS-DIFS
+@item Slot: The duration of a Slot.
+@item Pifs: The value of the PIFS constant.
+@item MaxPropagationDelay: The maximum propagation delay. Unused for now.
+@item MaxMsduSize: The maximum size of an MSDU accepted by the MAC layer.This value conforms to the specification.
+@item Ssid: The ssid we want to belong to.
+@end itemize
+
+@node Wifi Tracing
+@section Wifi Tracing
+
+@emph{This needs revised/updating based on the latest Doxygen}
+
+ns-3 has a sophisticated tracing infrastructure that allows users to hook
+into existing trace sources, or to define and export new ones.  
+
+Wifi-related trace sources that are available by default include:
+@itemize @bullet
+@item @code{ns3::WifiNetDevice}
+@itemize @bullet
+@item Rx: Received payload from the MAC layer.
+@item Tx: Send payload to the MAC layer.
+@end itemize
+@item @code{ns3::WifiPhy}
+@itemize @bullet
+@item State: The WifiPhy state
+@item RxOk: A packet has been received successfully.
+@item RxError: A packet has been received unsuccessfully.
+@item Tx: Packet transmission is starting.
+@end itemize
+@end itemize
+Briefly, this means, for example, that a user can hook a processing 
+function to the "State" tracing hook above and be notified whenever the
+WifiPhy model changes state.
--- a/doc/tutorial/building-topologies.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/tutorial/building-topologies.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -105,6 +105,13 @@
     LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
 @end verbatim
 
+A fixed seed is provided to the random number generators so that they will
+generate repeatable results.
+
+@verbatim
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+@end verbatim
+
 Next, you will see some familiar code that will allow you to change the number
 of devices on the CSMA network via command line argument.  We did something
 similar when we allowed the number of packets sent to be changed in the section
@@ -126,7 +133,7 @@
   p2pNodes.Create (2);
 @end verbatim
 
-Next, we delare another @code{NodeContainer} to hold the nodes that will be
+Next, we declare another @code{NodeContainer} to hold the nodes that will be
 part of the bus (CSMA) network.  First, we just instantiate the container
 object itself.  
 
@@ -163,10 +170,19 @@
 We mentioned above that you were going to see a helper for CSMA devices and
 channels, and the next lines introduce them.  The @code{CsmaHelper} works just
 like a @code{PointToPointHelper}, but it creates and connects CSMA devices and
-channels.
+channels.  In the case of a CSMA device and channel pair, notice that the data
+rate is specified by a @emph{channel} attribute instead of a device attribute.
+This is because a real CSMA network does not allow one to mix, for example, 
+10Base-T and 100Base-T devices on a given channel.  We first set the data rate
+to 100 megabits per second, and then set the speed-of-light delay of the channel
+to 6560 nano-seconds (arbitrarily chosen as 1 nanosecond per foot over a 100
+meter segment).  Notice that you can set an attribute using its native data 
+type.
 
 @verbatim
   CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
 
   NetDeviceContainer csmaDevices;
   csmaDevices = csma.Install (csmaNodes);
@@ -244,9 +260,9 @@
 Recall that the @code{csmaNodes NodeContainer} contains one of the 
 nodes created for the point-to-point network and @code{nCsma} ``extra'' nodes. 
 What we want to get at is the last of the ``extra'' nodes.  The zeroth entry of
-the @code{csmaNodes} container will the the point-to-point node.  The easy
+the @code{csmaNodes} container will be the point-to-point node.  The easy
 way to think of this, then, is if we create one ``extra'' CSMA node, then it
-will be be at index one of the @code{csmaNodes} container.  By induction,
+will be at index one of the @code{csmaNodes} container.  By induction,
 if we create @code{nCsma} ``extra'' nodes the last one will be at index 
 @code{nCsma}.  You see this exhibited in the @code{Get} of the first line of 
 code.
@@ -351,7 +367,7 @@
 
 Now look at @code{second-1-0.pcap} and @code{second-1-1.pcap}.  The former is
 the pcap trace for device zero on node one and the latter is the trace file 
-for device one on node one.  If you refer back to the topology illustrration at
+for device one on node one.  If you refer back to the topology illustration at
 the start of the section, you will see that node one is the node that has
 both a point-to-point device and a CSMA device, so we should expect two pcap
 traces for that node.
@@ -400,7 +416,7 @@
   ~/repos/ns-3-dev >
 @end verbatim
 
-As you can see, the link type is now ``Ethernet.''  Something new has appeared,
+As you can see, the link type is now ``Ethernet''.  Something new has appeared,
 though.  The bus network needs @code{ARP}, the Address Resolution Protocol.
 The node knows it needs to send the packet to IP address 10.1.2.4, but it
 doesn't know the MAC address of the corresponding node.  It broadcasts on the
@@ -429,7 +445,7 @@
   ~/repos/ns-3-dev >
 @end verbatim
 
-Again, you see that the link type is ``Ethernet.''  The first two entries are
+Again, you see that the link type is ``Ethernet''.  The first two entries are
 the ARP exchange we just explained.  The third packet is the echo packet 
 being delivered to its final destination.
 
@@ -648,6 +664,13 @@
     LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
 @end verbatim
 
+A fixed seed is provided to the random number generators so that they will
+generate repeatable results.
+
+@verbatim
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+@end verbatim
+
 Next, you will see more familiar code that will allow you to change the number
 of devices on the CSMA and Wifi networks via command line argument.
 
@@ -683,7 +706,7 @@
   p2pDevices = pointToPoint.Install (p2pNodes);
 @end verbatim
 
-Next, we delare another @code{NodeContainer} to hold the nodes that will be
+Next, we declare another @code{NodeContainer} to hold the nodes that will be
 part of the bus (CSMA) network.
 
 @verbatim
@@ -698,12 +721,15 @@
 point-to-point device and a CSMA device.  We then create a number of ``extra''
 nodes that compose the remainder of the CSMA network.
 
-We then instantiate a @code{CsmaHelper} and a @code{NetDeviceContainer} to 
-keep track of the CSMA net devices.  Then we @code{Install} CSMA devices on 
-the selected nodes.
+We then instantiate a @code{CsmaHelper} and set its attributes as we did in
+the previous example.  We create a @code{NetDeviceContainer} to keep track of
+the created CSMA net devices and then we @code{Install} CSMA devices on the 
+selected nodes.
 
 @verbatim
   CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
 
   NetDeviceContainer csmaDevices;
   csmaDevices = csma.Install (csmaNodes);
@@ -720,118 +746,42 @@
   NodeContainer wifiApNode = p2pNodes.Get (0);
 @end verbatim
 
-The next bit of code is going to be quite different from the helper-based
-topology generation we've seen so far, so we're going to take it line-by-line
-for a while.  The next line of code you will see is:
+The next bit of code constructs the wifi devices and the interconnection
+channel between these wifi nodes. First, we configure the PHY and channel
+helpers:
 
 @verbatim
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
+  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
 @end verbatim
 
-Now, I'm not going to explain at this stage @emph{precisely} what this all
-means, but hopefully with a very short digression I can give you enough 
-information so that this makes sense.
-
-C++ is an object oriented programming language.  @command{Ns-3} extends the
-basic C++ object model to implement a number of nifty features.  We have seen
-the @code{Attribute} system which is one of the major extensions we have 
-implemented.  Another extension is to provide for relatively automatic memory 
-management.  Like many systems, @command{ns-3} creates a base class called 
-@code{Object} that provides our extensions ``for free'' to other classes that
- inherit from our @code{class Object}.  
-
-In the code snippet above, the right hand side of the expression is a 
-call to a templated C++ function called @code{CreateObject}.  The 
-@emph{template parameter} inside the angle brackets basically tells the 
-compiler what class it is we want to instantiate.  Our system returns a
-@emph{smart pointer} to the object of the class that was created and assigns
-it to the smart pointer named @code{channel} that is declared on the left 
-hand side of the assignment.
-
-The @command{ns-3} smart pointer is also template-based.  Here you see that 
-we declare a smart pointer to a @code{WifiChannel} which is the type of object
-that was created in the @code{CreateObject} call.  The feature of immediate 
-interest here is that we are never going to have to delete the underlying C++
-object.  It is handled automatically for us.  Nice, eh?
-
-The idea to take away from this discussion is that this line of code creates
-an @command{ns-3} @code{Object} that will automatically bring you the benefits
-of the @command{ns-3} @code{Attribute} system we've seen previously.  The 
-resulting smart pointer works with the @code{Object} to perform memory 
-management automatically for you.  If you are interested in more details about
-low level ns-3 code and exactly what it is doing, you are encouraged to 
-explore the ns-3 manual and our ``how-to'' documents.
-
-Now, back to the example.  The line of code above has created a wireless
-@code{Wifi} channel.  This channel model requires that we create and attach 
-other models that describe various behaviors.  This provides an accomplished
-user with even more opportunity to change the way the wireless network behaves
-without changing the core code.
-
-The first opportunity we have to change the behavior of the wireless network is
-by providing a propagation delay model.  Again, I don't want to devolve this
-tutorial into a manual on @code{Wifi}, but this model describes how the 
-electromagnetic signals are going to propagate.  We are going to create the 
-simplest model, the @code{ConstantSpeedPropagationDelayModel} that, by default,
-has the signals propagating at a constant speed --- approximately that of the 
-speed of light in air.
-
-Recall that we created the @code{WifiChannel} and assigned it to a smart 
-pointer.  One of the features of a smart pointer is that you can use it
-just as you would a ``normal'' C++ pointer.  The next line of code will
-create a @code{ConstantSpeedPropagationDelayModel} using the 
-@code{CreateObject} template function and pass the resulting smart pointer
-to the chanel model as an unnamed parameter of the 
-@code{WifiChannel SetPropagationDelayModel} method.  In English, we create
-a model for propagation speed of electromagnetic signals and tell the 
-wireless channel to use it.
+For simplicity, this code uses the default PHY layer configuration and
+channel models which are documented in the API doxygen documentation for
+the @code{YansWifiChannelHelper::Default} and @code{YAnsWifiPhyHelper::Default}
+methods. Once these objects are created, we create a channel object
+and associate it to our PHY layer object manager to make sure
+that all the PHY objects created layer by the @code{YansWifiPhyHelper}
+all share the same underlying channel, that is, they share the same
+wireless medium and can communication and interfere:
 
 @verbatim
-  channel->SetPropagationDelayModel (
-    CreateObject<ConstantSpeedPropagationDelayModel> ());
-@end verbatim
-
-The next lines of code use similar low-level @command{ns-3} methods to create
-and set a ``propagation loss model'' for the channel.  
-
-@verbatim
-  Ptr<LogDistancePropagationLossModel> log =
-    CreateObject<LogDistancePropagationLossModel> ();
-
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
-
-  channel->SetPropagationLossModel (log);
+  phy.SetChannel (channel.Create ());
 @end verbatim
 
-This snippet is used to tell the channel how it should calculate signal 
-attenuation of waves flowing in the channel.  The details of these calcuations
-are beyond the scope of a tutorial.  You are encouraged to explore the Doxygen
-documentation of classes @code{LogDistancePropagationLossModel} and
-@code{FriisPropagationLossModel} if you are interested in the details.  As
-usual, you will find the documentation in the ``Classes'' tab of the Doxygen 
-documentation.
-
-Now we will return to more familiar ground.  We next create a @code{WifiHelper}
-object and set two default attributes that it will use when creating the actual
-devices.
+Once the PHY helper is configured, we can focus on the MAC layer:
 
 @verbatim
-  WifiHelper wifi;
-  wifi.SetPhy ("ns3::WifiPhy");
-  wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
+  WifiHelper wifi = WifiHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
 @end verbatim
 
-The @code{SetPhy} method tells the helper the type of physical layer class
-we want it to instantiate when building @code{Wifi} devices.  In this case,  
-the script is asking for physical layer models based on the YANS 802.11a 
-model.  Again, details are avialable in Doxygen.
 
 The @code{SetRemoteStationManager} method tells the helper the type of 
 rate control algorithm to use.  Here, it is asking the helper to use the AARF
-algorithm --- details are, of course, avialable in Doxygen.
+algorithm --- details are, of course, available in Doxygen.
 
-Just as we can vary attributes describing the physical layer, we can do the
-same for the MAC layer.
+Next, we configure the SSID of the infrastructure network we want to setup
+and make sure that our stations don't perform active probing:
 
 @verbatim
   Ssid ssid = Ssid ("ns-3-ssid");
@@ -848,15 +798,13 @@
 ``ActiveProbing'' attribute is set to false.  This means that probe requests
 will not be sent by MACs created by this helper.
 
-Again, for the next lines of code we are back on familiar ground.  This code
-will @code{Install} Wifi net devices on the nodes we have created as STA nodes
-and will tie them to the @code{WifiChannel}.  Since we created the 
-@code{channel} manually rather than having the helper do it for us, we have to
-pass it into the helper when we call the @code{Install} method.
+Once all the station-specific parameters are fully configured, both at the
+MAC and PHY layers, we can invoke our now-familiar @code{Install} method to 
+create the wifi devices of these stations:
 
 @verbatim
   NetDeviceContainer staDevices;
-  staDevices = wifi.Install (wifiStaNodes, channel);
+  staDevices = wifi.Install (phy, wifiStaNodes);
 @end verbatim
 
 We have configured Wifi for all of our STA nodes, and now we need to 
@@ -876,18 +824,18 @@
 ``BeaconGeneration'' attribute to true and also set an interval between 
 beacons of 2.5 seconds.
 
-The next lines create the single AP and connect it to the channel in a
-familiar way.
+The next lines create the single AP which shares the same set of PHY-level
+attributes (and channel) as the stations:
 
 @verbatim
   NetDeviceContainer apDevices;
-  apDevices = wifi.Install (wifiApNode, channel);
+  apDevices = wifi.Install (phy, wifiApNode);
 @end verbatim
 
 Now, we are going to add mobility models.  We want the STA nodes to be mobile,
 wandering around inside a bounding box, and we want to make the AP node 
 stationary.  We use the @code{MobilityHelper} to make this easy for us.
-First, we instantiate a @code{MobilityHelper} obejct and set some attributes
+First, we instantiate a @code{MobilityHelper} object and set some attributes
 controlling the ``position allocator'' functionality.
 
 @verbatim
@@ -906,7 +854,7 @@
 place the STA nodes.  Feel free to explore the Doxygen for class 
 @code{ns3::GridPositionAllocator} to see exactly what is being done.
 
-We have aranged our nodes on an initial grid, but now we need to tell them
+We have arranged our nodes on an initial grid, but now we need to tell them
 how to move.  We choose the @code{RandomWalk2dMobilityModel} which has the 
 nodes move in a random direction at a random speed around inside a bounding 
 box.
@@ -948,7 +896,7 @@
 @code{Ipv4AddressHelper} to assign IP addresses to our device interfaces.
 First we use the network 10.1.1.0 to create the two addresses needed for our
 two point-to-point devices.  Then we use network 10.1.2.0 to assign addresses
-the the CSMA network and then we assign addresses from network 10.1.3.0 to
+to the CSMA network and then we assign addresses from network 10.1.3.0 to
 both the STA devices and the AP on the wireless network.
 
 @verbatim
@@ -993,7 +941,7 @@
   clientApps.Stop (Seconds (10.0));
 @end verbatim
 
-Since we have built an internetwork here, we need enable internetwork routing
+Since we have built an internetwork here, we need to enable internetwork routing
 just as we did in the @code{second.cc} example script.
 
 @verbatim
--- a/doc/tutorial/conceptual-overview.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/tutorial/conceptual-overview.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -82,7 +82,7 @@
 @cindex Channel
 
 In the real world, one can connect a computer to a network.  Often the media
-over which data flows in these netowrks are called @emph{channels}.  When
+over which data flows in these networks are called @emph{channels}.  When
 you connect your Ethernet cable to the plug in the wall, you are connecting 
 your computer to an Ethernet communication channel.  In the simulated world
 of @command{ns-3}, one connects a @code{Node} to an object representing a
@@ -362,6 +362,21 @@
 INFO level for echo clients and servers.  This will result in the application
 printing out messages as packets are sent and received during the simulation.
 
+The next line of code is used to give a fixed seed to the random number 
+generators so that they will generate repeatable results.  In the example
+programs, it allows us to thouroughly document the output of the trace files
+in a consistent way.  Having a fixed seed also allows us to use the examples 
+in our regression testing framework.
+
+@verbatim
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+@end verbatim
+
+Random variables are very important in understanding how to get repeatable
+results, so you are encouraged to read the Doxygen and manual sections to
+understand what is going on there.  For us, the main concern is in making 
+random backoff algorithms consistent across runs.
+
 Now we will get directly to the business of creating a topology and running 
 a simulation.  We use the topology helper objects to make this job as
 easy as possible.
@@ -490,7 +505,7 @@
 by the @code{PointToPointHelper}, the attributes previously set in the helper
 are used to initialize the corresponding attributes in the created objects.
 
-After executing the the @code{pointToPoint.Install (nodes)} call we will have
+After executing the @code{pointToPoint.Install (nodes)} call we will have
 two nodes, each with an installed point-to-point net device and a 
 point-to-point channel between them.  Both devices will be configured to 
 transmit data at five megabits per second over the channel which has a two 
@@ -643,9 +658,9 @@
 
 Recall that we used an @code{Ipv4InterfaceContainer} to keep track of the IP 
 addresses we assigned to our devices.  The zeroth interface in the 
-@code{interfaces} container is going to coorespond to the IP address of the 
+@code{interfaces} container is going to correspond to the IP address of the 
 zeroth node in the @code{nodes} container.  The first interface in the 
-@code{interfaces} container cooresponds to the IP address of the first node 
+@code{interfaces} container corresponds to the IP address of the first node 
 in the @code{nodes} container.  So, in the first line of code (from above), we
 are creating the helper and telling it so set the remote address of the client
 to be  the IP address assigned to the node on which the server resides.  We 
@@ -741,7 +756,7 @@
 @end verbatim
 
 You can now run the example (note that if you build your program in the scratch
-directory you must run it out of the scratch direcory):
+directory you must run it out of the scratch directory):
 
 @verbatim
   ~/repos/ns-3-dev > ./waf --run scratch/first
--- a/doc/tutorial/in-process/introduction.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/tutorial/in-process/introduction.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -676,7 +676,7 @@
 @cindex Channel
 
 In the real world, one can connect a computer to a network.  Often the media
-over which data flows in these netowrks are called @emph{channels}.  When
+over which data flows in these networks are called @emph{channels}.  When
 you connect your Ethernet cable to the plug in the wall, you are connecting 
 your computer to an Ethernet communication channel.  In the simulated world
 of ns-3 one connects a @code{Node} to an object representing a
--- a/doc/tutorial/tweaking.texi	Sun Dec 07 19:02:55 2008 +0000
+++ b/doc/tutorial/tweaking.texi	Sun Dec 28 12:34:28 2008 +0000
@@ -744,7 +744,7 @@
 
 The rationale for this explicit division is to allow users to attach new
 types of sinks to existing tracing sources, without requiring editing and 
-recompilation of the the core of the simulator.  Thus, in the example above, 
+recompilation of the core of the simulator.  Thus, in the example above, 
 a user could define a new tracing sink in her script and attach it to an 
 existing tracing source defined in the simulation core by editing only the 
 user script.
@@ -885,7 +885,7 @@
 the final segments of the ``trace path'' which are @code{TxQueue/Enqueue}.
 
 The remaining lines in the trace should be fairly intuitive.  References 03-04
-indicate that the packet is encapulated in the point-to-point protocol.  
+indicate that the packet is encapsulated in the point-to-point protocol.  
 References 05-07 show that the packet has an IP version four header and has
 originated from IP address 10.1.1.1 and is destined for 10.1.1.2.  References
 08-09 show that this packet has a UDP header and, finally, reference 10 shows
@@ -952,7 +952,7 @@
 
 In our example script, we will eventually see files named ``first-0-0.pcap'' 
 and ``first.1-0.pcap'' which are the pcap traces for node 0-device 0 and 
-node 1-device 1, respectively.
+node 1-device 0, respectively.
 
 Once you have added the line of code to enable pcap tracing, you can run the
 script in the usual way:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic-global-routing.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,230 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ * Contributed by:  Luis Cortes (cortes@gatech.edu)
+ */
+
+
+// This script exercises global routing code in a mixed point-to-point
+// and csma/cd environment
+//
+// Network topology
+//
+//  n0
+//     \ p-p
+//      \          (shared csma/cd)
+//       n2 -------------------------n3
+//      /            |        | 
+//     / p-p        n4        n5 ---------- n6
+//   n1                             p-p
+//   |                                      |
+//   ----------------------------------------
+//                p-p
+//
+// - at time 1 CBR/UDP flow from n1 to n6's IP address on the n5/n6 link
+// - at time 10, start similar flow from n1 to n6's address on the n1/n6 link
+//
+//  Order of events
+//  At pre-simulation time, configure global routes.  Shortest path from
+//  n1 to n6 is via the direct point-to-point link
+//  At time 1s, start CBR traffic flow from n1 to n6
+//  At time 2s, set the n1 point-to-point interface to down.  Packets
+//    will start to be dropped 
+//  At time 3s, call RecomputeRoutingTables() and traffic will
+//    start flowing again on the alternate path
+//  At time 4s, re-enable the n1/n6 interface to up.  Will not change routing
+//  At time 5s, call RecomputeRoutingTables() and traffic will start flowing 
+//    again on the original path
+//  At time 6s, set the n6-n1 point-to-point Ipv4 interface to down (note, this
+//    keeps the point-to-point link "up" from n1's perspective).  Packets
+//    will traverse the link and be dropped at n6 upon receipt.  These drops
+//    are not visible in the pcap trace but in the ascii trace.
+//  At time 7s, call RecomputeRoutingTables() and traffic will flow again
+//    through the path n1-n2-n5-n6
+//  At time 8s, bring the interface back up.
+//  At time 9s, call RecomputeRoutingTables() and traffic will flow again
+//    through the path n1-n6
+//  At time 10s, stop the first flow.  
+//  At time 11s, start a new flow, but to n6's other IP address (the one
+//    on the n1/n6 p2p link)
+//  At time 12s, bring the n1 interface down between n1 and n6.  Packets
+//    will start to be dropped 
+//  At time 13s, call RecomputeRoutingTables() and traffic will
+//    start flowing again on the alternate path
+//  At time 14s, re-enable the n1/n6 interface to up.  Will not change routing
+//  At time 15s, call RecomputeRoutingTables() and traffic will start flowing 
+//    again on the original path
+//  At time 16s, stop the second flow.  
+
+// - Tracing of queues and packet receptions to file "dynamic-global-routing.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("DynamicGlobalRoutingExample");
+
+int 
+main (int argc, char *argv[])
+{
+  // Allow the user to override any of the defaults and the above
+  // Bind ()s at run-time, via command-line arguments
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer c;
+  c.Create (7);
+  NodeContainer n0n2 = NodeContainer (c.Get (0), c.Get (2));
+  NodeContainer n1n2 = NodeContainer (c.Get (1), c.Get (2));
+  NodeContainer n5n6 = NodeContainer (c.Get (5), c.Get (6));
+  NodeContainer n1n6 = NodeContainer (c.Get (1), c.Get (6));
+  NodeContainer n2345 = NodeContainer (c.Get (2), c.Get (3), c.Get (4), c.Get (5));
+
+  InternetStackHelper internet;
+  internet.Install (c);
+
+  // We create the channels first without any IP addressing information
+  NS_LOG_INFO ("Create channels.");
+  PointToPointHelper p2p;
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer d0d2 = p2p.Install (n0n2);
+  NetDeviceContainer d1d6 = p2p.Install (n1n6);
+
+  NetDeviceContainer d1d2 = p2p.Install (n1n2);
+
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
+  NetDeviceContainer d5d6 = p2p.Install (n5n6);
+
+  // We create the channels first without any IP addressing information
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
+  csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer d2345 = csma.Install (n2345);
+  
+  // Later, we add IP addresses.  
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  ipv4.Assign (d0d2);
+
+  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+  ipv4.Assign (d1d2);
+
+  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
+  Ipv4InterfaceContainer i5i6 = ipv4.Assign (d5d6);
+
+  ipv4.SetBase ("10.250.1.0", "255.255.255.0");
+  ipv4.Assign (d2345);
+
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i1i6 = ipv4.Assign (d1d6);
+
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  // 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)
+  OnOffHelper onoff ("ns3::UdpSocketFactory",
+                     InetSocketAddress (i5i6.GetAddress (1), port));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", StringValue ("2kbps"));
+  onoff.SetAttribute ("PacketSize", UintegerValue (50));
+
+  ApplicationContainer apps = onoff.Install (c.Get (1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  // Create a second OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  OnOffHelper onoff2 ("ns3::UdpSocketFactory",
+                     InetSocketAddress (i1i6.GetAddress (1), port));
+  onoff2.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff2.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff2.SetAttribute ("DataRate", StringValue ("2kbps"));
+  onoff2.SetAttribute ("PacketSize", UintegerValue (50));
+
+  ApplicationContainer apps2 = onoff2.Install (c.Get (1));
+  apps2.Start (Seconds (11.0));
+  apps2.Stop (Seconds (16.0));
+
+  // Create an optional packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  apps = sink.Install (c.Get (6));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  PacketSinkHelper sink2 ("ns3::UdpSocketFactory",
+    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  apps2 = sink2.Install (c.Get (6));
+  apps2.Start (Seconds (11.0));
+  apps2.Stop (Seconds (16.0));
+
+
+  std::ofstream ascii;
+  ascii.open ("dynamic-global-routing.tr");
+  PointToPointHelper::EnablePcapAll ("dynamic-global-routing");
+  PointToPointHelper::EnableAsciiAll (ascii);
+  CsmaHelper::EnablePcapAll ("dynamic-global-routing");
+  CsmaHelper::EnableAsciiAll (ascii);
+  InternetStackHelper::EnableAsciiAll (ascii);
+ 
+  Ptr<Node> n1 = c.Get (1);
+  Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
+  // The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
+  // then the next p2p is numbered 2
+  uint32_t ipv4ifIndex1 = 2;
+
+  Simulator::Schedule (Seconds (2),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
+  Simulator::Schedule (Seconds (3),&GlobalRouteManager::RecomputeRoutingTables);
+  Simulator::Schedule (Seconds (4),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
+  Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
+
+  Ptr<Node> n6 = c.Get (6);
+  Ptr<Ipv4> ipv46 = n6->GetObject<Ipv4> ();
+  // The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
+  // then the next p2p is numbered 2
+  uint32_t ipv4ifIndex6 = 2;
+  Simulator::Schedule (Seconds (6),&Ipv4::SetDown,ipv46, ipv4ifIndex6);
+  Simulator::Schedule (Seconds (7),&GlobalRouteManager::RecomputeRoutingTables);
+  Simulator::Schedule (Seconds (8),&Ipv4::SetUp,ipv46, ipv4ifIndex6);
+  Simulator::Schedule (Seconds (9),&GlobalRouteManager::RecomputeRoutingTables);
+
+  Simulator::Schedule (Seconds (12),&Ipv4::SetDown,ipv41, ipv4ifIndex1);
+  Simulator::Schedule (Seconds (13),&GlobalRouteManager::RecomputeRoutingTables);
+  Simulator::Schedule (Seconds (14),&Ipv4::SetUp,ipv41, ipv4ifIndex1);
+  Simulator::Schedule (Seconds (15),&GlobalRouteManager::RecomputeRoutingTables);
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- a/examples/first.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/examples/first.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -29,6 +29,8 @@
   LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
   LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
 
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
   NodeContainer nodes;
   nodes.Create (2);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/global-routing-slash32.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ */
+
+// Test program for this 3-router scenario, using global routing
+//
+// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/csma-net-device.h"
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("GlobalRouterSlash32Test");
+
+int 
+main (int argc, char *argv[])
+{
+  // Make the random number generators generate reproducible results.
+  //
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  // Allow the user to override any of the defaults and the above
+  // DefaultValue::Bind ()s at run-time, via command-line arguments
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  Ptr<Node> nA = CreateObject<Node> ();
+  Ptr<Node> nB = CreateObject<Node> ();
+  Ptr<Node> nC = CreateObject<Node> ();
+
+  NodeContainer c = NodeContainer (nA, nB, nC);
+
+  InternetStackHelper internet;
+  internet.Install (c);
+
+  // Point-to-point links
+  NodeContainer nAnB = NodeContainer (nA, nB);
+  NodeContainer nBnC = NodeContainer (nB, nC);
+
+  // We create the channels first without any IP addressing information
+  PointToPointHelper p2p;
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer dAdB = p2p.Install (nAnB);
+
+  NetDeviceContainer dBdC = p2p.Install (nBnC);;
+  
+  Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
+  deviceA->SetAddress (Mac48Address::Allocate ());
+  nA->AddDevice (deviceA);
+
+  Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
+  deviceC->SetAddress (Mac48Address::Allocate ());
+  nC->AddDevice (deviceC);
+
+  // Later, we add IP addresses.  
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
+
+  ipv4.SetBase ("10.1.1.4", "255.255.255.252");
+  Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
+
+  Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
+  Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
+  
+  int32_t ifIndexA = ipv4A->AddInterface (deviceA);
+  int32_t ifIndexC = ipv4C->AddInterface (deviceC);
+    
+  ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
+  ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
+  ipv4A->SetMetric (ifIndexA, 1);
+  ipv4A->SetUp (ifIndexA);
+
+  ipv4C->SetAddress (ifIndexC, Ipv4Address ("192.168.1.1"));
+  ipv4C->SetNetworkMask (ifIndexC, Ipv4Mask ("255.255.255.255"));
+  ipv4C->SetMetric (ifIndexC, 1);
+  ipv4C->SetUp (ifIndexC);
+ 
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  uint16_t port = 9;   // Discard port (RFC 863)
+  OnOffHelper onoff ("ns3::UdpSocketFactory", 
+    Address (InetSocketAddress (Ipv4Address("192.168.1.1"), port)));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
+  ApplicationContainer apps = onoff.Install (nA);
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  // Create a packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  apps = sink.Install (nC);
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  std::ofstream ascii;
+  ascii.open ("global-routing-slash32.tr");
+  PointToPointHelper::EnablePcapAll ("global-routing-slash32");
+  PointToPointHelper::EnableAsciiAll (ascii);
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return 0;
+}
--- a/examples/second.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/examples/second.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -1,102 +1,106 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "ns3/core-module.h"
-#include "ns3/simulator-module.h"
-#include "ns3/node-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/global-routing-module.h"
-
-// Default Network Topology
-//
-//       10.1.1.0
-// n0 -------------- n1   n2   n3   n4
-//    point-to-point  |    |    |    |
-//                    ================
-//                      LAN 10.1.2.0
-
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
-
-int 
-main (int argc, char *argv[])
-{
-  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
-  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
-
-  uint32_t nCsma = 3;
-  CommandLine cmd;
-  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
-  cmd.Parse (argc,argv);
-
-  NodeContainer p2pNodes;
-  p2pNodes.Create (2);
-
-  NodeContainer csmaNodes;
-  csmaNodes.Add (p2pNodes.Get (1));
-  csmaNodes.Create (nCsma);
-
-  PointToPointHelper pointToPoint;
-  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
-  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
-
-  NetDeviceContainer p2pDevices;
-  p2pDevices = pointToPoint.Install (p2pNodes);
-
-  CsmaHelper csma;
-
-  NetDeviceContainer csmaDevices;
-  csmaDevices = csma.Install (csmaNodes);
-
-  InternetStackHelper stack;
-  stack.Install (p2pNodes.Get (0));
-  stack.Install (csmaNodes);
-
-  Ipv4AddressHelper address;
-  address.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer p2pInterfaces;
-  p2pInterfaces = address.Assign (p2pDevices);
-
-  address.SetBase ("10.1.2.0", "255.255.255.0");
-  Ipv4InterfaceContainer csmaInterfaces;
-  csmaInterfaces = address.Assign (csmaDevices);
-
-  UdpEchoServerHelper echoServer (9);
-
-  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
-  serverApps.Start (Seconds (1.0));
-  serverApps.Stop (Seconds (10.0));
-
-  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
-  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
-  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
-  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
-
-  ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
-  clientApps.Start (Seconds (2.0));
-  clientApps.Stop (Seconds (10.0));
-
-  GlobalRouteManager::PopulateRoutingTables ();
-
-  PointToPointHelper::EnablePcapAll ("second");
-  CsmaHelper::EnablePcapAll ("second");
-
-  Simulator::Run ();
-  Simulator::Destroy ();
-  return 0;
-}
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+
+// Default Network Topology
+//
+//       10.1.1.0
+// n0 -------------- n1   n2   n3   n4
+//    point-to-point  |    |    |    |
+//                    ================
+//                      LAN 10.1.2.0
+
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
+
+int 
+main (int argc, char *argv[])
+{
+  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
+  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
+
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  uint32_t nCsma = 3;
+  CommandLine cmd;
+  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
+  cmd.Parse (argc,argv);
+
+  NodeContainer p2pNodes;
+  p2pNodes.Create (2);
+
+  NodeContainer csmaNodes;
+  csmaNodes.Add (p2pNodes.Get (1));
+  csmaNodes.Create (nCsma);
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer p2pDevices;
+  p2pDevices = pointToPoint.Install (p2pNodes);
+
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
+
+  NetDeviceContainer csmaDevices;
+  csmaDevices = csma.Install (csmaNodes);
+
+  InternetStackHelper stack;
+  stack.Install (p2pNodes.Get (0));
+  stack.Install (csmaNodes);
+
+  Ipv4AddressHelper address;
+  address.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer p2pInterfaces;
+  p2pInterfaces = address.Assign (p2pDevices);
+
+  address.SetBase ("10.1.2.0", "255.255.255.0");
+  Ipv4InterfaceContainer csmaInterfaces;
+  csmaInterfaces = address.Assign (csmaDevices);
+
+  UdpEchoServerHelper echoServer (9);
+
+  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
+  serverApps.Start (Seconds (1.0));
+  serverApps.Stop (Seconds (10.0));
+
+  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
+  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
+  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
+  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
+
+  ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
+  clientApps.Start (Seconds (2.0));
+  clientApps.Stop (Seconds (10.0));
+
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  PointToPointHelper::EnablePcapAll ("second");
+  CsmaHelper::EnablePcapAll ("second");
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/static-routing-slash32.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,137 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ *
+ */
+
+// Test program for this 3-router scenario, using static routing
+//
+// (a.a.a.a/32)A<--x.x.x.0/30-->B<--y.y.y.0/30-->C(c.c.c.c/32)
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/csma-net-device.h"
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("StaticRoutingSlash32Test");
+
+int 
+main (int argc, char *argv[])
+{
+  // Make the random number generators generate reproducible results.
+  //
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  // Allow the user to override any of the defaults and the above
+  // DefaultValue::Bind ()s at run-time, via command-line arguments
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  Ptr<Node> nA = CreateObject<Node> ();
+  Ptr<Node> nB = CreateObject<Node> ();
+  Ptr<Node> nC = CreateObject<Node> ();
+
+  NodeContainer c = NodeContainer (nA, nB, nC);
+
+  InternetStackHelper internet;
+  internet.Install (c);
+
+  // Point-to-point links
+  NodeContainer nAnB = NodeContainer (nA, nB);
+  NodeContainer nBnC = NodeContainer (nB, nC);
+
+  // We create the channels first without any IP addressing information
+  PointToPointHelper p2p;
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer dAdB = p2p.Install (nAnB);
+
+  NetDeviceContainer dBdC = p2p.Install (nBnC);;
+  
+  Ptr<CsmaNetDevice> deviceA = CreateObject<CsmaNetDevice> ();
+  deviceA->SetAddress (Mac48Address::Allocate ());
+  nA->AddDevice (deviceA);
+
+  Ptr<CsmaNetDevice> deviceC = CreateObject<CsmaNetDevice> ();
+  deviceC->SetAddress (Mac48Address::Allocate ());
+  nC->AddDevice (deviceC);
+
+  // Later, we add IP addresses.  
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.252");
+  Ipv4InterfaceContainer iAiB = ipv4.Assign (dAdB);
+
+  ipv4.SetBase ("10.1.1.4", "255.255.255.252");
+  Ipv4InterfaceContainer iBiC = ipv4.Assign (dBdC);
+
+  Ptr<Ipv4> ipv4A = nA->GetObject<Ipv4> ();
+  Ptr<Ipv4> ipv4B = nB->GetObject<Ipv4> ();
+  Ptr<Ipv4> ipv4C = nC->GetObject<Ipv4> ();
+  
+  int32_t ifIndexA = ipv4A->AddInterface (deviceA);
+  int32_t ifIndexC = ipv4C->AddInterface (deviceC);
+    
+  ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
+  ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
+  ipv4A->SetMetric (ifIndexA, 1);
+  ipv4A->SetUp (ifIndexA);
+
+  ipv4C->SetAddress (ifIndexC, Ipv4Address ("192.168.1.1"));
+  ipv4C->SetNetworkMask (ifIndexC, Ipv4Mask ("255.255.255.255"));
+  ipv4C->SetMetric (ifIndexC, 1);
+  ipv4C->SetUp (ifIndexC);
+ 
+  // Create static routes from A to C
+  // The ifIndex for this outbound route is 1; the first p2p link added
+  ipv4A->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.2"), 1);
+  // The ifIndex we want on node B is 2; 0 corresponds to loopback, and 1 to the first point to point link
+  ipv4B->AddHostRouteTo (Ipv4Address ("192.168.1.1"), Ipv4Address ("10.1.1.6"), 2);
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  uint16_t port = 9;   // Discard port (RFC 863)
+  OnOffHelper onoff ("ns3::UdpSocketFactory", 
+    Address (InetSocketAddress (Ipv4Address("192.168.1.1"), port)));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
+  ApplicationContainer apps = onoff.Install (nA);
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  // Create a packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  apps = sink.Install (nC);
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  std::ofstream ascii;
+  ascii.open ("static-routing-slash32.tr");
+  PointToPointHelper::EnablePcapAll ("static-routing-slash32");
+  PointToPointHelper::EnableAsciiAll (ascii);
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  return 0;
+}
--- a/examples/third.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/examples/third.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -1,172 +1,167 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "ns3/core-module.h"
-#include "ns3/simulator-module.h"
-#include "ns3/node-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/global-routing-module.h"
-#include "ns3/wifi-module.h"
-#include "ns3/mobility-module.h"
-
-// Default Network Topology
-//
-//   Wifi 10.1.3.0
-//                 AP   
-//  *    *    *    *
-//  |    |    |    |    10.1.1.0
-// n5   n6   n7   n0 -------------- n1   n2   n3   n4
-//                   point-to-point  |    |    |    |
-//                                   ================
-//                                     LAN 10.1.2.0
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
-
-int 
-main (int argc, char *argv[])
-{
-  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
-  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
-
-  uint32_t nCsma = 3;
-  uint32_t nWifi = 3;
-  CommandLine cmd;
-  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
-  cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
-  cmd.Parse (argc,argv);
-
-  NodeContainer p2pNodes;
-  p2pNodes.Create (2);
-
-  PointToPointHelper pointToPoint;
-  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
-  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
-
-  NetDeviceContainer p2pDevices;
-  p2pDevices = pointToPoint.Install (p2pNodes);
-
-  NodeContainer csmaNodes;
-  csmaNodes.Add (p2pNodes.Get (1));
-  csmaNodes.Create (nCsma);
-
-  CsmaHelper csma;
-
-  NetDeviceContainer csmaDevices;
-  csmaDevices = csma.Install (csmaNodes);
-
-  NodeContainer wifiStaNodes;
-  wifiStaNodes.Create (nWifi);
-  NodeContainer wifiApNode = p2pNodes.Get (0);
-
-  Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
-
-  channel->SetPropagationDelayModel (
-    CreateObject<ConstantSpeedPropagationDelayModel> ());
-
-  Ptr<LogDistancePropagationLossModel> log = 
-    CreateObject<LogDistancePropagationLossModel> ();
-
-  log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
-
-  channel->SetPropagationLossModel (log);
-
-  WifiHelper wifi;
-  wifi.SetPhy ("ns3::WifiPhy");
-  wifi.SetRemoteStationManager ("ns3::ArfWifiManager");
-
-  Ssid ssid = Ssid ("ns-3-ssid");
-  wifi.SetMac ("ns3::NqstaWifiMac", 
-    "Ssid", SsidValue (ssid),
-    "ActiveProbing", BooleanValue (false));
-
-  NetDeviceContainer staDevices;
-  staDevices = wifi.Install (wifiStaNodes, channel);
-
-  wifi.SetMac ("ns3::NqapWifiMac", 
-    "Ssid", SsidValue (ssid),
-    "BeaconGeneration", BooleanValue (true),
-    "BeaconInterval", TimeValue (Seconds (2.5)));
-
-  NetDeviceContainer apDevices;
-  apDevices = wifi.Install (wifiApNode, channel);
-
-  MobilityHelper mobility;
-
-  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
-    "MinX", DoubleValue (0.0),
-    "MinY", DoubleValue (0.0),
-    "DeltaX", DoubleValue (5.0),
-    "DeltaY", DoubleValue (10.0),
-    "GridWidth", UintegerValue (3),
-    "LayoutType", StringValue ("RowFirst"));
-
-  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
-    "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
-  mobility.Install (wifiStaNodes);
-
-  mobility.SetMobilityModel ("ns3::StaticMobilityModel");
-  mobility.Install (wifiApNode);
-
-  InternetStackHelper stack;
-  stack.Install (csmaNodes);
-  stack.Install (wifiApNode);
-  stack.Install (wifiStaNodes);
-
-  Ipv4AddressHelper address;
-
-  address.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer p2pInterfaces;
-  p2pInterfaces = address.Assign (p2pDevices);
-
-  address.SetBase ("10.1.2.0", "255.255.255.0");
-  Ipv4InterfaceContainer csmaInterfaces;
-  csmaInterfaces = address.Assign (csmaDevices);
-
-  address.SetBase ("10.1.3.0", "255.255.255.0");
-  address.Assign (staDevices);
-  address.Assign (apDevices);
-
-  UdpEchoServerHelper echoServer (9);
-
-  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
-  serverApps.Start (Seconds (1.0));
-  serverApps.Stop (Seconds (10.0));
-
-  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
-  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
-  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
-  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
-
-  ApplicationContainer clientApps = 
-    echoClient.Install (wifiStaNodes.Get (nWifi - 1));
-  clientApps.Start (Seconds (2.0));
-  clientApps.Stop (Seconds (10.0));
-
-  GlobalRouteManager::PopulateRoutingTables ();
-
-  Simulator::Stop (Seconds (10.0));
-
-  WifiHelper::EnablePcap ("third", 
-    wifiStaNodes.Get (nWifi - 1)->GetId (), 0);
-  CsmaHelper::EnablePcap ("third", 
-    csmaNodes.Get (nCsma)->GetId (), 0);
-
-  Simulator::Run ();
-  Simulator::Destroy ();
-  return 0;
-}
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-routing-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+
+// Default Network Topology
+//
+//   Wifi 10.1.3.0
+//                 AP   
+//  *    *    *    *
+//  |    |    |    |    10.1.1.0
+// n5   n6   n7   n0 -------------- n1   n2   n3   n4
+//                   point-to-point  |    |    |    |
+//                                   ================
+//                                     LAN 10.1.2.0
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
+
+int 
+main (int argc, char *argv[])
+{
+  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
+  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
+
+  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+  uint32_t nCsma = 3;
+  uint32_t nWifi = 3;
+  CommandLine cmd;
+  cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
+  cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
+  cmd.Parse (argc,argv);
+
+  NodeContainer p2pNodes;
+  p2pNodes.Create (2);
+
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+  NetDeviceContainer p2pDevices;
+  p2pDevices = pointToPoint.Install (p2pNodes);
+
+  NodeContainer csmaNodes;
+  csmaNodes.Add (p2pNodes.Get (1));
+  csmaNodes.Create (nCsma);
+
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
+  csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
+
+  NetDeviceContainer csmaDevices;
+  csmaDevices = csma.Install (csmaNodes);
+
+  NodeContainer wifiStaNodes;
+  wifiStaNodes.Create (nWifi);
+  NodeContainer wifiApNode = p2pNodes.Get (0);
+
+  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
+  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+  phy.SetChannel (channel.Create ());
+
+  WifiHelper wifi = WifiHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
+
+  Ssid ssid = Ssid ("ns-3-ssid");
+  wifi.SetMac ("ns3::NqstaWifiMac", 
+    "Ssid", SsidValue (ssid),
+    "ActiveProbing", BooleanValue (false));
+
+  NetDeviceContainer staDevices;
+  staDevices = wifi.Install (phy, wifiStaNodes);
+
+  wifi.SetMac ("ns3::NqapWifiMac", 
+    "Ssid", SsidValue (ssid),
+    "BeaconGeneration", BooleanValue (true),
+    "BeaconInterval", TimeValue (Seconds (2.5)));
+
+  NetDeviceContainer apDevices;
+  apDevices = wifi.Install (phy, wifiApNode);
+
+  MobilityHelper mobility;
+
+  mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
+    "MinX", DoubleValue (0.0),
+    "MinY", DoubleValue (0.0),
+    "DeltaX", DoubleValue (5.0),
+    "DeltaY", DoubleValue (10.0),
+    "GridWidth", UintegerValue (3),
+    "LayoutType", StringValue ("RowFirst"));
+
+  mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
+    "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
+  mobility.Install (wifiStaNodes);
+
+  mobility.SetMobilityModel ("ns3::StaticMobilityModel");
+  mobility.Install (wifiApNode);
+
+  InternetStackHelper stack;
+  stack.Install (csmaNodes);
+  stack.Install (wifiApNode);
+  stack.Install (wifiStaNodes);
+
+  Ipv4AddressHelper address;
+
+  address.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer p2pInterfaces;
+  p2pInterfaces = address.Assign (p2pDevices);
+
+  address.SetBase ("10.1.2.0", "255.255.255.0");
+  Ipv4InterfaceContainer csmaInterfaces;
+  csmaInterfaces = address.Assign (csmaDevices);
+
+  address.SetBase ("10.1.3.0", "255.255.255.0");
+  address.Assign (staDevices);
+  address.Assign (apDevices);
+
+  UdpEchoServerHelper echoServer (9);
+
+  ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
+  serverApps.Start (Seconds (1.0));
+  serverApps.Stop (Seconds (10.0));
+
+  UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
+  echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
+  echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
+  echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
+
+  ApplicationContainer clientApps = 
+    echoClient.Install (wifiStaNodes.Get (nWifi - 1));
+  clientApps.Start (Seconds (2.0));
+  clientApps.Stop (Seconds (10.0));
+
+  GlobalRouteManager::PopulateRoutingTables ();
+
+  Simulator::Stop (Seconds (10.0));
+
+  YansWifiPhyHelper::EnablePcap ("third", 
+    wifiStaNodes.Get (nWifi - 1)->GetId (), 0);
+  CsmaHelper::EnablePcap ("third", 
+    csmaNodes.Get (nCsma)->GetId (), 0);
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+  return 0;
+}
--- a/examples/wscript	Sun Dec 07 19:02:55 2008 +0000
+++ b/examples/wscript	Sun Dec 28 12:34:28 2008 +0000
@@ -4,10 +4,34 @@
     obj = bld.create_ns3_program('hello-simulator')
     obj.source = 'hello-simulator.cc'
         
+    obj = bld.create_ns3_program('first',
+                                 ['core', 'simulator', 'point-to-point', 'internet-stack'])
+    obj.source = 'first.cc'
+        
+    obj = bld.create_ns3_program('second',
+                                 ['core', 'simulator', 'point-to-point', 'csma', 'internet-stack'])
+    obj.source = 'second.cc'
+        
+    obj = bld.create_ns3_program('third',
+                                 ['core', 'simulator', 'point-to-point', 'csma', 'wifi', 'internet-stack'])
+    obj.source = 'third.cc'
+        
     obj = bld.create_ns3_program('mixed-wireless',
                                  ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack'])
     obj.source = 'mixed-wireless.cc'
 
+    obj = bld.create_ns3_program('dynamic-global-routing',
+                                 ['point-to-point', 'csma', 'internet-stack', 'global-routing'])
+    obj.source = 'dynamic-global-routing.cc'
+
+    obj = bld.create_ns3_program('static-routing-slash32',
+                                 ['point-to-point', 'internet-stack', 'global-routing'])
+    obj.source = 'static-routing-slash32.cc'
+
+    obj = bld.create_ns3_program('global-routing-slash32',
+                                 ['point-to-point', 'internet-stack', 'global-routing'])
+    obj.source = 'global-routing-slash32.cc'
+
     obj = bld.create_ns3_program('simple-global-routing',
                                  ['point-to-point', 'internet-stack', 'global-routing'])
     obj.source = 'simple-global-routing.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-dynamic-global-routing.py	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate):
+    """Execute a test."""
+
+    return tracediff.run_test(verbose, generate, "dynamic-global-routing")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-global-routing-slash32.py	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate):
+    """Execute a test."""
+
+    return tracediff.run_test(verbose, generate, "global-routing-slash32")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-second.py	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate):
+    """Execute a test."""
+
+    return tracediff.run_test(verbose, generate, "second")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-static-routing-slash32.py	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate):
+    """Execute a test."""
+
+    return tracediff.run_test(verbose, generate, "static-routing-slash32")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-third.py	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate):
+    """Execute a test."""
+
+    return tracediff.run_test(verbose, generate, "third")
--- a/src/applications/onoff/onoff-application.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/applications/onoff/onoff-application.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -165,7 +165,8 @@
     { // Cancel the pending send packet event
       // Calculate residual bits since last packet sent
       Time delta(Simulator::Now() - m_lastStartTime);
-      m_residualBits += (uint32_t)(m_cbrRate.GetBitRate() * delta.GetSeconds());
+      Scalar bits = delta * Scalar (m_cbrRate.GetBitRate ()) / Seconds (1.0);
+      m_residualBits += (uint32_t)bits.GetDouble ();
     }
   Simulator::Cancel(m_sendEvent);
   Simulator::Cancel(m_startStopEvent);
@@ -177,13 +178,15 @@
   NS_LOG_FUNCTION_NOARGS ();
 
   ScheduleNextTx();  // Schedule the send packet event
+  ScheduleStopEvent();
 }
 
 void OnOffApplication::StopSending()
 {
   NS_LOG_FUNCTION_NOARGS ();
+  CancelEvents();
 
-  Simulator::Cancel(m_sendEvent);
+  ScheduleStartEvent();
 }
 
 // Private helpers
@@ -222,7 +225,7 @@
 
   Time onInterval = Seconds(m_onTime.GetValue());
   NS_LOG_LOGIC ("stop at " << onInterval);
-  Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this);
+  m_startStopEvent = Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this);
 }
 
   
--- a/src/applications/packet-sink/packet-sink.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/applications/packet-sink/packet-sink.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -119,6 +119,10 @@
   Address from;
   while (packet = socket->RecvFrom (from))
     {
+      if (packet->GetSize() == 0)
+        { //EOF
+	  break;
+        }
       if (InetSocketAddress::IsMatchingType (from))
         {
           InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
--- a/src/applications/v4ping/v4ping.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/applications/v4ping/v4ping.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -108,6 +108,15 @@
     }
 }
 
+void
+V4Ping::Write32 (uint8_t *buffer, uint32_t data)
+{
+  buffer[0] = (data >> 0) & 0xff;
+  buffer[1] = (data >> 8) & 0xff;
+  buffer[2] = (data >> 16) & 0xff;
+  buffer[3] = (data >> 24) & 0xff;
+}
+
 void 
 V4Ping::StartApplication (void)
 {
@@ -128,13 +137,28 @@
   echo.SetSequenceNumber (m_seq);
   m_seq++;
   echo.SetIdentifier (0);
-  uint32_t data[4];
-  data[0] = GetNode ()->GetId ();
-  data[1] = GetApplicationId ();
+
+  //
+  // We must write quantities out in some form of network order.  Since there
+  // isn't an htonl to work with we just follow the convention in pcap traces
+  // (where any difference would show up anyway) and borrow that code.  Don't
+  // be too surprised when you see that this is a little endian convention.
+  //
+  uint8_t data[4 * sizeof(uint32_t)];
+  uint32_t tmp = GetNode ()->GetId ();
+  Write32 (&data[0 * sizeof(uint32_t)], tmp);
+
+  tmp = GetApplicationId ();
+  Write32 (&data[1 * sizeof(uint32_t)], tmp);
+
   int64_t now = Simulator::Now ().GetTimeStep ();
-  data[2] = now & 0xffffffff;
+  tmp = now & 0xffffffff;
+  Write32 (&data[2 * sizeof(uint32_t)], tmp);
+
   now >>= 32;
-  data[3] = now & 0xffffffff;
+  tmp = now & 0xffffffff;
+  Write32 (&data[3 * sizeof(uint32_t)], tmp);
+
   Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) &data, 16);
   echo.SetData (dataPacket);
   p->AddHeader (echo);
--- a/src/applications/v4ping/v4ping.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/applications/v4ping/v4ping.h	Sun Dec 28 12:34:28 2008 +0000
@@ -18,6 +18,8 @@
   virtual ~V4Ping ();
 
 private:
+  void Write32 (uint8_t *buffer, uint32_t data);
+
   // inherited from Application base class.
   virtual void StartApplication (void);
   virtual void StopApplication (void);
--- a/src/common/data-rate.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/common/data-rate.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -36,64 +36,104 @@
     std::string trailer = s.substr(n, std::string::npos);
     if (trailer == "bps")
       {
-        // Bit/s
+        // bit/s
         *v = (uint64_t)r;
       }
     else if (trailer == "b/s")
       {
-        // Bit/s
+        // bit/s
         *v = (uint64_t)r;
       }
     else if (trailer == "Bps")
       {
-        // Byte/s
+        // byte/s
         *v = (uint64_t)(r * 8);
       }
     else if (trailer == "B/s") 
       {
-        // Byte/s
+        // byte/s
         *v = (uint64_t)(r * 8);
       }
     else if (trailer == "kbps")
       {
-        // KiloBit/s
+        // kilobits/s
         *v = (uint64_t)(r * 1000);
       }
     else if (trailer == "kb/s")
       {
-        // KiloBit/s
+        // kilobits/s
+        *v = (uint64_t)(r * 1000);
+      }
+    else if (trailer == "Kbps")
+      {
+        // kilobits/s
+        *v = (uint64_t)(r * 1000);
+      }
+    else if (trailer == "Kb/s")
+      {
+        // kilobits/s
         *v = (uint64_t)(r * 1000);
       }
     else if (trailer == "kBps")
       {
-        // KiloBit/s
-        *v = (uint64_t)(r * 1000);
+        // kiloByte/s
+        *v = (uint64_t)(r * 8000);
       }
     else if (trailer == "kB/s")
       {
-        // KiloBit/s
-        *v = (uint64_t)(r * 1000);
+        // KiloByte/s
+        *v = (uint64_t)(r * 8000);
+      }
+    else if (trailer == "KBps")
+      {
+        // kiloByte/s
+        *v = (uint64_t)(r * 8000);
+      }
+    else if (trailer == "KB/s")
+      {
+        // KiloByte/s
+        *v = (uint64_t)(r * 8000);
+      }
+    else if (trailer == "Kib/s")
+      {
+        // kibibit/s
+        *v = (uint64_t)(r * 1024);
+      }
+    else if (trailer == "KiB/s")
+      {
+        // kibibyte/s
+        *v = (uint64_t)(r * 8192);
       }
     else if (trailer == "Mbps")
       {
-        // MegaBit/s
+        // MegaBits/s
         *v = (uint64_t)(r * 1000000);
       }
     else if (trailer == "Mb/s")
       {
-        // MegaBit/s
+        // MegaBits/s
         *v = (uint64_t)(r * 1000000);
       }
     else if (trailer == "MBps")
       {
-        // MegaByte/s
+        // MegaBytes/s
         *v = (uint64_t)(r * 8000000);
       }
     else if (trailer == "MB/s")
       {
-        // MegaByte/s
+        // MegaBytes/s
         *v = (uint64_t)(r * 8000000);
       }
+    else if (trailer == "Mib/s")
+      {
+        // MebiBits/s
+        *v = (uint64_t)(r * 1048576);
+      }
+    else if (trailer == "MiB/s")
+      {
+        // MebiByte/s
+        *v = (uint64_t)(r * 1048576 * 8);
+      }
     else if (trailer == "Gbps")
       {
         // GigaBit/s
@@ -114,6 +154,16 @@
         // GigaByte/s
         *v = (uint64_t)(r * 8*1000000000);
       }
+    else if (trailer == "Gib/s")
+      {
+        // GibiBits/s
+        *v = (uint64_t)(r * 1048576 * 1024);
+      }
+    else if (trailer == "GiB/s")
+      {
+        // GibiByte/s
+        *v = (uint64_t)(r * 1048576 * 1024 * 8);
+      }
     else
       {
         return false;
--- a/src/common/data-rate.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/common/data-rate.h	Sun Dec 28 12:34:28 2008 +0000
@@ -48,6 +48,25 @@
  * \endcode
  * This class also supports the regular comparison operators <, >, <=, >=, ==,
  * and !=
+ *
+ * Conventions used:
+ * "b" stands for bits, "B" for bytes (8 bits) \n
+ * "k" stands for 1000, "K" also stands for 1000, "Ki" stands for 1024 \n
+ * "M" stand for 1000000, "Mib" stands for 1024 kibibits, or 1048576 bits \n
+ * "G" stand for 10^9, "Gib" stands for 1024 mebibits \n
+ * whitespace is allowed but not required between the numeric value and units
+ *
+ * Supported unit strings:
+ * bps, b/s, Bps, B/s \n
+ * kbps, kb/s, Kbps, Kb/s, kBps, kB/s, KBps, KB/s, Kib/s, KiB/s \n
+ * Mbps, Mb/s, MBps, MB/s, Mib/s, MiB/s \n
+ * Gbps, Gb/s, GBps, GB/s, Gib/s, GiB/s \n
+ * 
+ * Examples:
+ * "56kbps" = 56,000 bits/s \n
+ * "128 kb/s" = 128,000 bits/s \n
+ * "8Kib/s" = 1 KiB/s = 8192 bits/s \n
+ * "1kB/s" = 8000 bits/s 
  */
 class DataRate
 {
--- a/src/core/attribute.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/core/attribute.h	Sun Dec 28 12:34:28 2008 +0000
@@ -144,7 +144,7 @@
  * to detect the type of the associated attribute.
  *
  * Most subclasses of this base class are implemented by the 
- * \ref ATTRIBUTE_HELPER_HEADER and \ref ATTRIBUTE_HELPER_CPP macros.
+ * ATTRIBUTE_HELPER_HEADER and ATTRIBUTE_HELPER_CPP macros.
  */
 class AttributeChecker : public RefCountBase
 {
--- a/src/core/config.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/core/config.h	Sun Dec 28 12:34:28 2008 +0000
@@ -111,26 +111,97 @@
  */
 void Disconnect (std::string path, const CallbackBase &cb);
 
+/**
+ * \brief hold a set of objects which match a specific search string.
+ *
+ * This class also allows you to perform a set of configuration operations
+ * on the set of matching objects stored in the container. Specifically,
+ * it is possible to perform bulk Connects and Sets.
+ */
 class MatchContainer
 {
 public:
   typedef std::vector<Ptr<Object> >::const_iterator Iterator;
   MatchContainer ();
+  // constructor used only by implementation.
   MatchContainer (const std::vector<Ptr<Object> > &objects, 
                   const std::vector<std::string> &contexts, 
                   std::string path);
 
+  /**
+   * \returns an iterator which points to the first item in the container
+   */
   MatchContainer::Iterator Begin (void) const;
+  /**
+   * \returns an iterator which points to the last item in the container
+   */
   MatchContainer::Iterator End (void) const;
+  /**
+   * \returns the number of items in the container
+   */
   uint32_t GetN (void) const;
+  /**
+   * \param i index of item to lookup ([0,n[)
+   * \returns the item requested.
+   */
   Ptr<Object> Get (uint32_t i) const;
+  /**
+   * \param i index of item to lookup ([0,n[)
+   * \returns the fully-qualified matching path associated
+   *          to the requested item.
+   *
+   * The matching patch uniquely identifies the requested object.
+   */
   std::string GetMatchedPath (uint32_t i) const;
+  /**
+   * \returns the path used to perform the object matching.
+   */
   std::string GetPath (void) const;
 
+  /**
+   * \param name name of attribute to set
+   * \param value value to set to the attribute
+   *
+   * Set the specified attribute value to all the objects stored in this
+   * container.
+   * \sa ns3::Config::Set
+   */
   void Set (std::string name, const AttributeValue &value);
+  /**
+   * \param name the name of the trace source to connect to
+   * \param cb the sink to connect to the trace source
+   *
+   * Connect the specified sink to all the objects stored in this
+   * container.
+   * \sa ns3::Config::Connect
+   */
   void Connect (std::string name, const CallbackBase &cb);
+  /**
+   * \param name the name of the trace source to connect to
+   * \param cb the sink to connect to the trace source
+   *
+   * Connect the specified sink to all the objects stored in this
+   * container.
+   * \sa ns3::Config::ConnectWithoutContext     
+   */
   void ConnectWithoutContext (std::string name, const CallbackBase &cb);
+  /**
+   * \param name the name of the trace source to disconnect from
+   * \param cb the sink to disconnect from the trace source
+   *
+   * Disconnect the specified sink from all the objects stored in this
+   * container.
+   * \sa ns3::Config::Disconnect
+   */
   void Disconnect (std::string name, const CallbackBase &cb);
+  /**
+   * \param name the name of the trace source to disconnect from
+   * \param cb the sink to disconnect from the trace source
+   *
+   * Disconnect the specified sink from all the objects stored in this
+   * container.
+   * \sa ns3::Config::DisconnectWithoutContext
+   */
   void DisconnectWithoutContext (std::string name, const CallbackBase &cb);
 private:
   std::vector<Ptr<Object> > m_objects;
@@ -138,6 +209,11 @@
   std::string m_path;
 };
 
+/**
+ * \param path the path to perform a match against
+ * \returns a container which contains all the objects which match the input
+ *          path.
+ */
 MatchContainer LookupMatches (std::string path);
 
 /**
--- a/src/core/type-id.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/core/type-id.h	Sun Dec 28 12:34:28 2008 +0000
@@ -44,23 +44,14 @@
 class TypeId
 {
 public:
+  /**
+   * Flags describing when a given attribute can be read or written
+   */
   enum AttributeFlag {
-    /**
-     * The attribute can be read
-     */
-    ATTR_GET = 1<<0,
-    /**
-     * The attribute can be written
-     */
-    ATTR_SET = 1<<1,
-    /**
-     * The attribute can be written at construction-time.
-     */
-    ATTR_CONSTRUCT = 1<<2,
-    /**
-     * The attribute can be read, and written at any time.
-     */
-    ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
+    ATTR_GET = 1<<0, /**< The attribute can be read */
+    ATTR_SET = 1<<1, /**< The attribute can be written */
+    ATTR_CONSTRUCT = 1<<2, /**< The attribute can be written at construction-time */
+    ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT, /** The attribute can be read, and written at any time */
   };
 
   /**
--- a/src/devices/csma/csma-net-device.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/csma/csma-net-device.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -83,10 +83,10 @@
                    MakePointerAccessor (&CsmaNetDevice::m_queue),
                    MakePointerChecker<Queue> ())
     .AddTraceSource ("Rx", 
-                     "The trace source to fire on reception of a MAC packet.",
+                     "Trace source indicating reception of packet destined for broadcast, multicast or local address.",
                      MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace))
     .AddTraceSource ("Drop", 
-                     "Trace source to fire on when a MAC packet is dropped.",
+                     "Trace source indicating packet discarded due to receiver disabled or error model decision.",
                      MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace))
     ;
   return tid;
--- a/src/devices/csma/csma.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/csma/csma.h	Sun Dec 28 12:34:28 2008 +0000
@@ -1,8 +1,8 @@
 /**
  * \ingroup devices
- * \defgroup CSMA CSMA Model
+ * \defgroup CsmaModel CSMA Model
  *
- * \section CSMA Model
+ * \section CsmaModelOverview CSMA Model Overview
  *
  * The ns-3 CSMA device models a simple bus network in the spirit of Ethernet.
  * Although it does not model any real physical network you could ever build 
@@ -18,27 +18,87 @@
  * so the ns-3 CSMA device does not model collision detection, nor will any
  * transmission in progress be "jammed."
  *
- * \subsection CSMA Channel Model
+ * \section CsmaLayerModel CSMA Layer Model
+ *
+ * There are a number of conventions in use for describing layered 
+ * communications architectures in the literature and in textbooks.  The most
+ * common layering  model is the ISO seven layer reference model.  In this view
+ * the ns3::CsmaNetDevice and ns3::CsmaChannel pair occupies the lowest two 
+ * layers -- at the physical (layer one), and data link (layer two) positions.
+ * Another important reference model is that specified by RFC 1122, 
+ * "Requirements for Internet Hosts -- Communication Layers."  In this view the
+ * CsmaNetDevice and CsmaChannel pair occupies the lowest layer -- 
+ * the link layer.  There is also a seemingly endless litany of alternative 
+ * descriptions found in textbooks and in the literature.  We adopt the naming
+ * conventions used in the IEEE 802 standards which speak of LLC, MAC, MII
+ * and PHY layering.  These acronyms are defined as:
+ *
+ * - LLC:  Logical Link Control;
+ * - MAC:  Media Access Control;
+ * - MII:  Media Independent Interface;
+ * - PHY:  Physical Layer.
+ * 
+ * In this case the LLC and MAC are sublayers of the OSI data link layer and the 
+ * MII and PHY are sublayers of the OSI physical layer.
+ *
+ * The "top" of the CSMA device defines the transition from the network layer
+ * to the data link layer.  This transition is performed by higher layers by 
+ * calling either ns3::CsmaNetDevice::Send or ns3::CsmaNetDevice::SendFrom.
  *
- * The class ns3::CsmaChannel models the actual transmission medium.
+ * In contrast to the IEEE 802.3 standards, there is no precisely specified
+ * PHY in the CSMA model in the sense of wire types, signals or pinouts.  The
+ * "bottom" interface of the CsmaNetDevice can be thought of as as a kind
+ * of Media Independent Interface (MII) as seen in the "Fast Ethernet" 
+ * (IEEE 802.3u) specifications.  This MII interface fits into a corresponding
+ * media independent interface on the CsmaChannel.  You will not find the
+ * equivalent of a 10BASE-T or a 1000BASE-LX PHY.
+ *
+ * The CsmaNetDevice calls the CsmaChannel through a media independent
+ * interface.  There is a method defined to tell the channel when to start 
+ * "wiggling the wires" using the method ns3::CsmaChannel::TransmitStart, and 
+ * a method to tell the channel when the transmission process is done and
+ * the channel should begin propagating the last bit across the "wire":
+ * ns3::CsmaChannel::TransmitEnd.
+ *
+ * When the TransmitEnd method is executed, the channel will model a single 
+ * uniform signal propagation delay in the medium and deliver copes of the packet
+ * to each of the devices attached to the packet via the 
+ * ns3::CsmaNetDevice::Receive method.
+ *
+ * There is a "pin" in the device media independent interface corresponding to 
+ * "COL" (collision).  The state of the channel may be sensed by calling 
+ * ns3::CsmaChannel::GetState.  Each device will look at this "pin" before 
+ * starting a send and will perform appropriate backoff operations if required.
+ *
+ * Properly received packets are forwarded up to higher levels from the 
+ * CsmaNetDevice via a callback mechanism.  The callback function is
+ * initialized by the higher layer (when the net device is attached) using
+ * ns3::CsmaNetDevice::SetReceiveCallback and is invoked upon "proper"
+ *  reception of a packet by the net device in order to forward the packet up
+ * the protocol stack.
+ *
+ * \section CsmaChannelModel CSMA Channel Model
+ *
+ * The class CsmaChannel models the actual transmission medium.
  * There is no fixed limit for the number of devices connected to the channel.
- * The ns3::CsmaChannel models a data rate and a speed-of-light delay which can
+ * The CsmaChannel models a data rate and a speed-of-light delay which can
  * be accessed via the attributes "DataRate" and "Delay" respectively.
  * The data rate provided to the channel is used to set the data rates
  * used by the transmitter sections of the CSMA devices connected to the 
  * channel.  There is no way to independently set data rates in the
  * devices.  Since the data rate is only used to calculate a delay time, there
  * is no limitation (other than by the data type holding the value) on the 
- * speed at which CSMA channels and devices can operate.
+ * speed at which CSMA channels and devices can operate; and no restriction
+ * based on any kind of PHY characteristics.
  *
- * The ns3::CsmaChannel has three states, IDLE, TRANSMITTING and PROPAGATING.
+ * The CsmaChannel has three states, IDLE, TRANSMITTING and PROPAGATING.
  * These three states are "seen" instantaneously by all devices on the channel.
  * By this we mean that if one device begins or ends a simulated transmission,
  * all devices on the channel are immediately aware of the change in state.
  * There is no time during which one device may see an IDLE channel while
  * another device physically further away in the collision domain may have 
  * begun transmitting with the associated signals not propagated.  Thus there
- * is no need for collision detection in the ns3::CsmaChannel model and it is
+ * is no need for collision detection in the CsmaChannel model and it is
  * not implemented in any way.
  *
  * We do, as the name indicates, have a Carrier Sense aspect to the model.
@@ -66,22 +126,22 @@
  * in which the packet bits propagate to a central location and then back out
  * equal length cables to the other devices on the channel.
  *
- * The ns3::CsmaChannel models a broadcast medium so the packet is delivered
+ * The CsmaChannel models a broadcast medium so the packet is delivered
  * to all of the devices on the channel (including the source) at the end of 
  * the propagation time.  It is the responsibility of the sending device to 
  * determine whether or not it receives a packet broadcast over the channel.
  *
- * The ns3::CsmaChannel provides following Attributes:
+ * The CsmaChannel provides following Attributes:
  *
  * - DataRate:      The bitrate for packet transmission on connected devices;
  * - Delay:       The speed of light transmission delay for the channel.
  *
- * \subsection CSMA Net Device Model
+ * \section CsmaNetDeviceModel CSMA Net Device Model
  *
  * The CSMA network device appears somewhat like an Ethernet device.  The
- * ns3::CsmaNetDevice provides following Attributes:
+ * CsmaNetDevice provides following Attributes:
  *
- * - Address:           The ns3::Mac48Address of the device;
+ * - Address:           The Mac48Address of the device;
  * - SendEnable:        Enable packet transmission if true;
  * - ReceiveEnable:     Enable packet reception if true;
  * - EncapsulationMode: Type of link layer encapsulation to use;
@@ -91,37 +151,115 @@
  * - Rx:                A trace source for received packets;
  * - Drop:              A trace source for dropped packets.
  *
- * The ns3::CsmaNetDevice supports the assignment of a "receive error model."
- * This is an ns3::ErrorModel object that is used to simulate data corruption
+ * The CsmaNetDevice supports the assignment of a "receive error model."
+ * This is an ErrorModel object that is used to simulate data corruption
  * on the link.
  *
- * Packets sent over the ns3::CsmaNetDevice are always routed through the 
+ * Packets sent over the CsmaNetDevice are always routed through the 
  * transmit queue to provide a trace hook for packets sent out over the 
  * network.  This transmit queue can be set (via attribute) to model different
  * queueing strategies.
  *
  * Also configurable by attribute is the encapsulation method used by the
- * device.  Every packet gets an ns3::EthernetHeader that includes the 
- * destination and source MAC addresses, and a length/type field.  Every packet
- * also gets an ns3::EthernetTrailer which includes the FCS.  Data in the
- * packet may be encapsulated in different ways.  By default, or by setting
- * the "EncapsulationMode" attribute to "Llc", the encapsulation is by 
+ * device.  By default, or by setting the "EncapsulationMode" attribute to 
+ * "Dix", the encapsulation is according to the DEC, Intel, Xerox standard.
+ * This is sometimes called EthernetII framing and is the familiar destination
+ * MAC, source MAC, EtherType, Data, CRC format.
+ *
+ * If the "EncapsulationMode" attribute is set to "Llc", the encapsulation is by 
  * LLC SNAP.  In this case, a SNAP header is added that contains the EtherType
- * (IP or ARP).  The other implemented encapsulation modes are IP_ARP (set
- * "EncapsulationMode" to "IpArp") in which the length type of the Ethernet 
- * header receives the protocol number of the packet; or ETHERNET_V1 (set
- * "EncapsulationMode" to "EthernetV1") in which the length type of the 
- * Ethernet header receives the length of the packet.  A "Raw" encapsulation
- * mode is defined but not implemented -- use of the RAW mode results in an
- * assert firing.
+ * (IP or ARP).  
  *
- * The ns3::CsmaNetDevice implements a random exponential backoff algorithm 
+ * The other implemented encapsulation modes are IP_ARP (set "EncapsulationMode"
+ * to "IpArp") in which the length type of the Ethernet header receives the 
+ * protocol number of the packet; or ETHERNET_V1 (set "EncapsulationMode" to 
+ * "EthernetV1") in which the length type of the Ethernet header receives the 
+ * length of the packet.  A "Raw" encapsulation mode is defined but not 
+ * implemented -- use of the RAW mode results in an assertion.
+ *
+ * The CsmaNetDevice implements a random exponential backoff algorithm 
  * that is executed if the channel is determined to be busy (TRANSMITTING or
  * PROPAGATING) when the device wants to start propagating.  This results in a
  * random delay of up to pow (2, retries) - 1 microseconds before a retry is
  * attempted.  The default maximum number of retries is 1000.
  *
- * \subsection CSMA Model Summary
+ * \section CsmaTracingModel CSMA Tracing Model
+ *
+ * Like all ns-3 devices, the CSMA Model provides a number of trace sources.
+ * These trace sources can be hooked using your own custom trace code, or you
+ * can use our helper functions to arrange for tracing to be enabled on devices
+ * you specify.
+ *
+ * \subsection CsmaTracingModelUpperHooks Upper-Level (MAC) Hooks
+ *
+ * From the point of view of tracing in the net device, there are several 
+ * interesting points to insert trace hooks.  A convention inherited from other
+ * simulators is that packets destined for transmission onto attached networks
+ * pass through a single "transmit queue" in the net device.  We provide trace 
+ * hooks at this point in packet flow, which corresponds (abstractly) only to a 
+ * transition from the network to data link layer, and call them collectively
+ * the device MAC hooks.
+ *
+ * When a packet is sent to the CSMA net device for transmission it always 
+ * passes through the transmit queue.  The transmit queue in the 
+ * CsmaNetDevice inherits from Queue, and therefore inherits three 
+ * trace sources:
+ *
+ * - An Enqueue operation source (see Queue::m_traceEnqueue);
+ * - A Dequeue operation source (see Queue::m_traceDequeue);
+ * - A Drop operation source (see Queue::m_traceDrop).
+ *
+ * The upper-level (MAC) trace hooks for the CsmaNetDevice are, in fact, 
+ * exactly these three trace sources on the single transmit queue of the device.  
+ *
+ * The m_traceEnqueue event is triggered when a packet is placed on the transmit
+ * queue.  This happens at the time that ns3::CsmaNetDevice::Send or 
+ * ns3::CsmaNetDevice::SendFrom is called by a higher layer to queue a packet for 
+ * transmission.
+ *
+ * The m_traceDequeue event is triggered when a packet is removed from the
+ * transmit queue.  Dequeues from the transmit queue can happen in three 
+ * situations:  1) If the underlying channel is idle when the 
+ * CsmaNetDevice::Send or CsmaNetDevice::SendFrom is called, a packet
+ * is dequeued from the transmit queue and immediately transmitted;  2) If the
+ * underlying channel is idle, a packet may be dequeued and immediately 
+ * transmitted in an internal TransmitCompleteEvent that functions much 
+ * like a transmit complete interrupt service routine; or 3) from
+ * the random exponential backoff handler if a timeout is detected.
+ *
+ * Case (3) implies that a packet is dequeued from the transmit queue if it is 
+ * unable to be transmittted according to the backoff rules.  It is important 
+ * to understand that this will appear as a Dequeued packet and it is easy to 
+ * incorrectly assume that the packet was transmitted since it passed through
+ * the transmit queue.  In fact, a packet is actually dropped by the net device
+ * in this case.  The reason for this behavior is due to the definition of the 
+ * Queue Drop event.  The m_traceDrop event is, by defintion, fired when a 
+ * packet cannot be enqueued on the transmit queue becasue it is full.  This 
+ * event only fires if the queue is full and we do not overload this event
+ * to indicate that the CsmaChannel is "full."
+ *
+ * \subsection CsmaTracingModelUpperHooks Lower-Level (PHY) Hooks
+ *
+ * Similar to the upper level trace hooks, there are trace hooks available at
+ * the lower levels of the net device.  We call these the PHY hooks.  These 
+ * events fire from the device methods that talk directly to the CsmaChannel.
+ *
+ * The trace source m_dropTrace is called to indicate a packet that is dropped
+ * by the device.  This happens in two cases:  First, if the receive side of 
+ * the net device is not enabled (see ns3::CsmaNetDevice::m_receiveEnable and the 
+ * associated attribute "ReceiveEnable").
+ *
+ * The m_dropTrace is also used to indicate that a packet was discarded as 
+ * corrupt if a receive error model is used (see 
+ * ns3::CsmaNetDevice::m_receiveErrorModel and the associated attribute 
+ * "ReceiveErrorModel").
+ *
+ * The other low-level trace source fires on reception of an accepted packet
+ * (see ns3::CsmaNetDevice::m_rxTrace).  A packet is accepted if it is destined
+ * for the broadcast address, a multicast address, or to the MAC address 
+ * assigned to the net device.
+ *
+ * \section CsmaModelSummary CSMA Model Summary
  *
  * The ns3 CSMA model is a simplistic model of an Ethernet-like network.  It
  * supports a Carrier-Sense function and allows for Multiple Access to a 
@@ -136,10 +274,12 @@
  *
  * Ns-3 Attributes provide a mechanism for setting various parameters in the 
  * device and channel such as addresses, encapsulation modes and error model
- * selection.  Trace hooks are provided in the usual manner.
+ * selection.  Trace hooks are provided in the usual manner with a set of 
+ * upper level hooks corresponding to a transmit queue and used in ASCII 
+ * tracing; and also a set of lower level hooks used in pcap tracing.
  *
  * Although the ns-3 CsmaChannel and CsmaNetDevice does not model any kind of
  * network you could build or buy, it does provide us with some useful 
  * functionality.  You should, however, understand that it is explicitly not 
- * Ethernet or IEEE 802.3 but an interesting subset.
+ * Ethernet or any flavor of IEEE 802.3 but an interesting subset.
  */
--- a/src/devices/emu/emu-net-device.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/emu/emu-net-device.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -88,11 +88,8 @@
                    MakePointerAccessor (&EmuNetDevice::m_queue),
                    MakePointerChecker<Queue> ())
     .AddTraceSource ("Rx", 
-                     "Trace source to fire on reception of a MAC packet.",
+                     "Trace source indicating recvfrom of packet destined for broadcast, multicast or local address.",
                      MakeTraceSourceAccessor (&EmuNetDevice::m_rxTrace))
-    .AddTraceSource ("Drop", 
-                     "Trace source to fire on when a MAC packet is dropped.",
-                     MakeTraceSourceAccessor (&EmuNetDevice::m_dropTrace))
     ;
   return tid;
 }
--- a/src/devices/emu/emu.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/emu/emu.h	Sun Dec 28 12:34:28 2008 +0000
@@ -1,8 +1,8 @@
 /**
  * \ingroup devices
- * \defgroup Emulated Emulated Net Device Model
+ * \defgroup EmuModel Emulated Net Device Model
  *
- * \section Emulated Net Device Model
+ * \section EmuModelOverview Emulated Net Device Model Overview
  *
  * The emulated net device allows a simulation node to send and receive packets
  * a real network.
@@ -57,4 +57,58 @@
  * implication this has for static global routing.  The global router module
  * attempts to walk the channels looking for adjacent networks.  Since there 
  * is no channel, the global router will be unable to do this.
+ *
+ * \section EmuTracingModel Emulated Net Device Tracing Model
+ *
+ * Like all ns-3 devices, the Emu Model provides a number of trace sources.
+ * These trace sources can be hooked using your own custom trace code, or you
+ * can use our helper functions to arrange for tracing to be enabled on devices
+ * you specify.
+ *
+ * \subsection EmuTracingModelUpperHooks Upper-Level (MAC) Hooks
+ *
+ * From the point of view of tracing in the net device, there are several 
+ * interesting points to insert trace hooks.  A convention inherited from other
+ * simulators is that packets destined for transmission onto attached networks
+ * pass through a single "transmit queue" in the net device.  We provide trace 
+ * hooks at this point in packet flow, which corresponds (abstractly) only to a 
+ * transition from the network to data link layer, and call them collectively
+ * the device MAC hooks.
+ *
+ * When a packet is sent to the Emu net device for transmission it always 
+ * passes through the transmit queue.  The transmit queue in the EmuNetDevice
+ * inherits from Queue, and therefore inherits three trace sources:
+ *
+ * - An Enqueue operation source (see Queue::m_traceEnqueue);
+ * - A Dequeue operation source (see Queue::m_traceDequeue);
+ * - A Drop operation source (see Queue::m_traceDrop).
+ *
+ * The upper-level (MAC) trace hooks for the EmuNetDevice are, in fact, 
+ * exactly these three trace sources on the single transmit queue of the device.  
+ *
+ * The m_traceEnqueue event is triggered when a packet is placed on the transmit
+ * queue.  This happens at the time that ns3::EmuNetDevice::Send or 
+ * ns3::EmuNetDevice::SendFrom is called by a higher layer to queue a packet for 
+ * transmission.
+ *
+ * The m_traceDequeue event is triggered when a packet is removed from the
+ * transmit queue.  Dequeues from the transmit queue happen immediately after
+ * the packet was enqueued and only indicate that the packet is about to be
+ * sent to an underlying raw socket.  The actual time at which the packet is
+ * sent out on the wire is not available.
+ *
+ * \subsection EmuTracingModelLowerHooks Lower-Level (PHY) Hooks
+ *
+ * Similar to the upper level trace hooks, there are trace hooks available at
+ * the lower levels of the net device.  We call these the PHY hooks.  These 
+ * events fire from the device methods that talk directly to the underlying
+ * raw socket.
+ *
+ * The trace source m_dropTrace is not used in the Emu net device since that
+ * is really the business of the underlying "real" device driver.
+ *
+ * The other low-level trace source fires on reception of an accepted packet
+ * (see ns3::EmuNetDevice::m_rxTrace).  A packet is accepted if it is destined
+ * for the broadcast address, a multicast address, or to the MAC address 
+ * assigned to the Emu net device.
  */
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -73,11 +73,10 @@
                    MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
                    MakeTimeChecker ())
     .AddTraceSource ("Rx", 
-                     "Trace source to fire on reception of a MAC packet.",
+                     "Trace source indicating reception of packet from the PointToPointChannel.",
                      MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace))
     .AddTraceSource ("Drop",
-                     "Trace source to fire on when a MAC packet is dropped.",
-
+                     "Trace source indicating a packet was discarded due to a ReceiveErrorModel decision.",
                      MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace))
 
     ;
--- a/src/devices/point-to-point/point-to-point.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/point-to-point/point-to-point.h	Sun Dec 28 12:34:28 2008 +0000
@@ -1,8 +1,8 @@
 /**
  * \ingroup devices
- * \defgroup PointToPoint Point-to-Point Model
+ * \defgroup PointToPointModel Point-to-Point Model
  *
- * \section Point-to-Point Model
+ * \section PointToPointPointOverview Point-to-Point Model Overview
  *
  * The ns-3 point-to-point model is of a very simple point to point data link
  * connecting exactly two ns3::PointToPointNetDevice devices over an
@@ -21,17 +21,17 @@
  * for IP Version 4 which is the sixteen-bit number 0x21 (see
  * http://www.iana.org/assignments/ppp-numbers).
  *
- * The ns3::PointToPointNetDevice provides following Attributes:
+ * The PointToPointNetDevice provides following Attributes:
  *
  * - Address:       The ns3::Mac48Address of the device (if desired);
- * - DataRate:      The data rate of the device;
- * - TxQueue:       The trasmit queue used by the device;
- * - InterframeGap: The optional time to wait between "frames";
+ * - DataRate:      The data rate (ns3::DataRate) of the device;
+ * - TxQueue:       The trasmit queue (ns3::Queue) used by the device;
+ * - InterframeGap: The optional ns3::Time to wait between "frames";
  * - Rx:            A trace source for received packets;
  * - Drop:          A trace source for dropped packets.
  *
- * The ns3::PointToPointNetDevice models a transmitter section that puts bits
- * on a corresponding channel "wire."  THe DataRate attribute specifies the
+ * The PointToPointNetDevice models a transmitter section that puts bits
+ * on a corresponding channel "wire."  `The DataRate attribute specifies the
  * number of bits per second that the device will simulate sending over the 
  * channel.  In reality no bits are sent, but an event is scheduled for an
  * elapsed time consistent with the number of bits in each packet and the 
@@ -39,21 +39,95 @@
  * models a receiver section that can receive any any data rate.  Therefore
  * there is no need, nor way to set a receive data rate in this model.  By
  * setting the DataRate on the transmitter of both devices connected to a 
- * given ns3::PointToPointChannel one can model a symmetric channel; or by 
+ * given PointToPointChannel one can model a symmetric channel; or by 
  * setting different DataRates one can model an asymmetric channel (e.g., 
  * ADSL).
  *
- * The ns3::PointToPointNetDevice supports the assignment of a "receive error 
+ * The PointToPointNetDevice supports the assignment of a "receive error 
  * model."  This is an ns3::ErrorModel object that is used to simulate data
  * corruption on the link.
  *
+ * \section PointToPointChannelModel Point-to-Point Channel Model
+
  * The point to point net devices are connected via an 
  * ns3::PointToPointChannel.  This channel models two wires transmitting bits
  * at the data rate specified by the source net device.  There is no overhead
  * beyond the eight bits per byte of the packet sent.  That is, we do not 
  * model Flag Sequences, Frame Check Sequences nor do we "escape" any data.
  *
- * The ns3::PointToPointNetChannel provides following Attributes:
+ * The PointToPointNetChannel provides following Attributes:
+ *
+ * - Delay:  An ns3::Time specifying the speed of light transmission delay for
+ *   the channel.
+ *
+ * \section PointToPointTracingModel Point-to-Point Tracing Model
+ *
+ * Like all ns-3 devices, the Point-to-Point Model provides a number of trace 
+ * sources.  These trace sources can be hooked using your own custom trace code,
+ * or you can use our helper functions to arrange for tracing to be enabled on 
+ * devices you specify.
+ *
+ * \subsection PointToPointTracingModelUpperHooks Upper-Level (MAC) Hooks
+ *
+ * From the point of view of tracing in the net device, there are several 
+ * interesting points to insert trace hooks.  A convention inherited from other
+ * simulators is that packets destined for transmission onto attached networks
+ * pass through a single "transmit queue" in the net device.  We provide trace 
+ * hooks at this point in packet flow, which corresponds (abstractly) only to a 
+ * transition from the network to data link layer, and call them collectively
+ * the device MAC hooks.
+ *
+ * When a packet is sent to the Point-to-Point net device for transmission it 
+ * always passes through the transmit queue.  The transmit queue in the 
+ * PoiintToPointNetDevice inherits from Queue, and therefore inherits three 
+ * trace sources:
+ *
+ * - An Enqueue operation source (see Queue::m_traceEnqueue);
+ * - A Dequeue operation source (see Queue::m_traceDequeue);
+ * - A Drop operation source (see Queue::m_traceDrop).
+ *
+ * The upper-level (MAC) trace hooks for the PointToPointNetDevice are, in fact, 
+ * exactly these three trace sources on the single transmit queue of the device.  
  *
- * - Delay:       The speed of light transmission delay for the channel.
+ * The m_traceEnqueue event is triggered when a packet is placed on the transmit
+ * queue.  This happens at the time that ns3::PointtoPointNetDevice::Send or 
+ * ns3::PointToPointNetDevice::SendFrom is called by a higher layer to queue a 
+ * packet for transmission.  An Enqueue trace event firing should be interpreted
+ * as only indicating that a higher level protocol has sent a packet to the device.
+ *
+ * The m_traceDequeue event is triggered when a packet is removed from the
+ * transmit queue.  Dequeues from the transmit queue can happen in two
+ * situations:  1) If the underlying channel is idle when 
+ * PointToPointNetDevice::Send is called, a packet is dequeued from the transmit
+ * queue and immediately transmitted;  2) a packet may be dequeued and 
+ * immediately transmitted in an internal TransmitCompleteEvent that functions 
+ * much  like a transmit complete interrupt service routine.  An Dequeue trace 
+ * event firing may be viewed as indicating that the PointToPointNetDevice has
+ * begun transmitting a packet.
+ *
+ * \subsection CsmaTracingModelUpperHooks Lower-Level (PHY) Hooks
+ *
+ * Similar to the upper level trace hooks, there are trace hooks available at
+ * the lower levels of the net device.  We call these the PHY hooks.  These 
+ * events fire from the device methods that talk directly to the 
+ * PointToPointChannel.
+ *
+ * The trace source m_dropTrace is called to indicate a packet that is dropped
+ * by the device.  This happens when a packet is discarded as corrupt due to a 
+ * receive error model indication (see ns3::ErrorModel and the associated 
+ * attribute "ReceiveErrorModel").
+ *
+ * The other low-level trace source fires on reception of a packet (see 
+ * ns3::PointToPointNetDevice::m_rxTrace) from the PointToPointChannel.
+ *
+ * \section PointToPointModelSummary Point-To-Point Model Summary
+ *
+ * The ns3 Point-to-Point model is a simplistic model of a point to point
+ * serial line link.
+ *
+ * Ns-3 Attributes provide a mechanism for setting various parameters in the 
+ * device and channel such as data rates, speed-of-light delays and error model
+ * selection.  Trace hooks are provided in the usual manner with a set of 
+ * upper level hooks corresponding to a transmit queue and used in ASCII 
+ * tracing; and also a set of lower level hooks used in pcap tracing.
  */
--- a/src/devices/wifi/adhoc-wifi-mac.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/wifi/adhoc-wifi-mac.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -33,6 +33,9 @@
 
 NS_OBJECT_ENSURE_REGISTERED (AdhocWifiMac);
 
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
+
 TypeId 
 AdhocWifiMac::GetTypeId (void)
 {
--- a/src/devices/wifi/mac-low.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/wifi/mac-low.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -31,8 +31,9 @@
 
 NS_LOG_COMPONENT_DEFINE ("MacLow");
 
-#define MY_DEBUG(x) \
-  NS_LOG_DEBUG (m_self << " " << x)
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
+
 
 namespace ns3 {
 
@@ -457,7 +458,7 @@
 
   //NS_ASSERT (m_phy->IsStateIdle ());
 
-  MY_DEBUG ("startTx size="<< GetSize (m_currentPacket, &m_currentHdr) << 
+  NS_LOG_DEBUG ("startTx size="<< GetSize (m_currentPacket, &m_currentHdr) << 
             ", to=" << m_currentHdr.GetAddr1()<<", listener="<<m_listener);
 
   if (m_txParams.MustSendRts ()) 
@@ -477,7 +478,7 @@
 MacLow::ReceiveError (Ptr<const Packet> packet, double rxSnr)
 {
   NS_LOG_FUNCTION (this << packet << rxSnr);
-  MY_DEBUG ("rx failed ");
+  NS_LOG_DEBUG ("rx failed ");
   if (m_txParams.MustWaitFastAck ()) 
     {
       NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
@@ -500,7 +501,7 @@
   packet->RemoveHeader (hdr);
   
   bool isPrevNavZero = IsNavZero ();
-  MY_DEBUG ("duration/id=" << hdr.GetDuration ());
+  NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
   NotifyNav (hdr, txMode, preamble);
   if (hdr.IsRts ()) 
     {
@@ -513,7 +514,7 @@
       if (isPrevNavZero &&
           hdr.GetAddr1 () == m_self) 
         {
-          MY_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
+          NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
           NS_ASSERT (m_sendCtsEvent.IsExpired ());
           WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
           station->ReportRxOk (rxSnr, txMode);
@@ -526,7 +527,7 @@
         } 
       else 
         {
-          MY_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
+          NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
         }
     } 
   else if (hdr.IsCts () &&
@@ -534,7 +535,7 @@
            m_ctsTimeoutEvent.IsRunning () &&
            m_currentPacket != 0) 
     {
-      MY_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
+      NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
       SnrTag tag;
       packet->FindFirstMatchingTag (tag);
       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
@@ -557,7 +558,7 @@
             m_superFastAckTimeoutEvent.IsRunning ()) &&
            m_txParams.MustWaitAck ()) 
     {
-      MY_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
+      NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
       SnrTag tag;
       packet->FindFirstMatchingTag (tag);
       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
@@ -588,7 +589,7 @@
     } 
   else if (hdr.IsCtl ()) 
     {
-      MY_DEBUG ("rx drop " << hdr.GetTypeString ());
+      NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
     } 
   else if (hdr.GetAddr1 () == m_self) 
     {
@@ -597,11 +598,11 @@
       
       if (hdr.IsQosData () && hdr.IsQosNoAck ()) 
         {
-          MY_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
+          NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
         } 
       else if (hdr.IsData () || hdr.IsMgt ()) 
         {
-          MY_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
+          NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
           NS_ASSERT (m_sendAckEvent.IsExpired ());
           m_sendAckEvent = Simulator::Schedule (GetSifs (),
                                                 &MacLow::SendAckAfterData, this,
@@ -616,7 +617,7 @@
     {
       if (hdr.IsData () || hdr.IsMgt ()) 
         {
-          MY_DEBUG ("rx broadcast from=" << hdr.GetAddr2 ());
+          NS_LOG_DEBUG ("rx broadcast from=" << hdr.GetAddr2 ());
           goto rxPacket;
         } 
       else 
@@ -626,7 +627,7 @@
     } 
   else 
     {
-      //MY_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
+      //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet));
     }
   return;
  rxPacket:
@@ -825,7 +826,7 @@
                      WifiMode txMode)
 {
   NS_LOG_FUNCTION (this << packet << hdr << txMode);
-  MY_DEBUG ("send " << hdr->GetTypeString () <<
+  NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
             ", to=" << hdr->GetAddr1 () <<
             ", size=" << packet->GetSize () <<
             ", mode=" << txMode <<
@@ -845,7 +846,7 @@
 MacLow::CtsTimeout (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("cts timeout");
+  NS_LOG_DEBUG ("cts timeout");
   // XXX: should check that there was no rx start before now.
   // we should restart a new cts timeout now until the expected
   // end of rx if there was a rx start before now.
@@ -860,7 +861,7 @@
 MacLow::NormalAckTimeout (void)
 {
   NS_LOG_FUNCTION (this);
-  MY_DEBUG ("normal ack timeout");
+  NS_LOG_DEBUG ("normal ack timeout");
   // XXX: should check that there was no rx start before now.
   // we should restart a new ack timeout now until the expected
   // end of rx if there was a rx start before now.
@@ -880,12 +881,12 @@
   m_listener = 0;
   if (m_phy->IsStateIdle ()) 
     {
-      MY_DEBUG ("fast Ack idle missed");
+      NS_LOG_DEBUG ("fast Ack idle missed");
       listener->MissedAck ();
     }
   else
     {
-      MY_DEBUG ("fast Ack ok");
+      NS_LOG_DEBUG ("fast Ack ok");
     }
 }
 void
@@ -898,12 +899,12 @@
   m_listener = 0;
   if (m_phy->IsStateIdle ()) 
     {
-      MY_DEBUG ("super fast Ack failed");
+      NS_LOG_DEBUG ("super fast Ack failed");
       listener->MissedAck ();
     } 
   else 
     {
-      MY_DEBUG ("super fast Ack ok");
+      NS_LOG_DEBUG ("super fast Ack ok");
       listener->GotAck (0.0, WifiMode ());
     }
 }
@@ -1128,7 +1129,7 @@
   MacLowTransmissionListener *listener = m_listener;
   m_listener = 0;
   listener->MissedAck ();
-  MY_DEBUG ("fast Ack busy but missed");
+  NS_LOG_DEBUG ("fast Ack busy but missed");
 }
 
 void
--- a/src/devices/wifi/nqap-wifi-mac.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -37,6 +37,9 @@
 
 NS_OBJECT_ENSURE_REGISTERED (NqapWifiMac);
 
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
+
 TypeId 
 NqapWifiMac::GetTypeId (void)
 {
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -36,6 +36,9 @@
 
 NS_LOG_COMPONENT_DEFINE ("NqstaWifiMac");
 
+#undef NS_LOG_APPEND_CONTEXT
+#define NS_LOG_APPEND_CONTEXT if (m_low != 0) {std::clog << "[mac=" << m_low->GetAddress () << "] ";}
+
 /*
  * The state machine for this NQSTA is:
  --------------                                          -----------
--- a/src/devices/wifi/wifi.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/devices/wifi/wifi.h	Sun Dec 28 12:34:28 2008 +0000
@@ -2,7 +2,7 @@
  * \ingroup devices
  * \defgroup Wifi Wifi Models
  *
- * \section Wifi Models
+ * \section WifiModelOverview Wifi Models Overview
  *
  * The set of 802.11 models provided in ns-3 attempts to provide
  * an accurate MAC-level implementation of the 802.11 specification
@@ -15,7 +15,6 @@
  *   - the so-called MAC high models: they implement the MAC-level
  *     beacon generation, probing, and association state machines.
  *   - a set of Rate control algorithms used by the MAC low models.
- * 
  *
  * We have today 3 MAC high models:
  *   - a simple adhoc state machine which does not perform any
@@ -49,7 +48,61 @@
  *   - ns3::OnoeMacStations
  *   - ns3::AmrrMacStations
  *
- * \section Wifi Tutorial
+ * \section WifiTracingModel Wifi Tracing Model
+ *
+ * Like all ns-3 devices, the Wifi Model provides a number of trace sources.
+ * These trace sources can be hooked using your own custom trace code, or you
+ * can use our helper functions to arrange for tracing to be enabled on devices
+ * you specify.
+ *
+ * \subsection WifiTracingModelUpperHooks Upper-Level (MAC) Hooks
+ *
+ * From the point of view of tracing in the net device, there are several 
+ * interesting points to insert trace hooks.  The first is at the interface
+ * between the device and higher layers.  We provide trace hooks at this point
+ * in packet flow, which corresponds to a transition from the network to data 
+ * link layer, and call them collectively the device MAC hooks.
+ *
+ * The first trace hook is called "Rx" and is fired using the 
+ * ns3::WifiNetDevice::m_rxLogger trace hook.  The perspective here is looking
+ * down into the WifiNetDevice so a receive indicates a packet being sent up
+ * from the channel to be forwarded up to higher layers.
+ *
+ * The second trace hook is called "Tx" and is fired using the 
+ * ns3::WifiNetDevice::m_txLogger trace hook.  This trace hook indicates a 
+ * packet has been sent from higher layers down to the net device for 
+ * transmission onto the network.
+ *
+ * \subsection WifiTracingModelLowerHooks Low-Level (PHY) Hooks
  *
+ * Another interesting place to insert trace hooks is in the state machine
+ * that is driving the actual device transmission and reception logic.  We 
+ * provide the following hooks to instrument the lower levels of the device.
  *
+ * First, we provide a trace hook to indicate state changes.  This trace
+ * source is called "State" and is fired using the 
+ * ns3::WifiPhyStateHelper::m_stateLogger trace source.
+ *
+ * We also provide a trace hook to indicate the successful reception of a
+ * packet from the channel.  This trace source is called "RxOk" and is 
+ * accessed using the ns3::WifiPhyStateHelper::m_rxOkTrace trace source.
+ *
+ * There also exists a trace hook to indicate an unsuccessful reception of a
+ * packet from the channel.  This trace source is called "RxError" and is 
+ * accessed using the ns3::WifiPhyStateHelper::m_rxErrorTrace trace source.
+ *
+ * There is a trace hook to indicate that transmission of a packet is 
+ * starting onto the channel.  This trace source is called "Tx" (don't 
+ * confuse it with the higher layer "Tx" hook) and is 
+ * fired using the ns3::WifiPhyStateHelper::m_txTrace trace source.
+ *
+ * \subsection WifiTracingModelRemoteHooks Remote Station Hooks
+ *
+ * We provide access to changes in the the per-remote-station RTS counter 
+ * through the "Ssrc" trace source which is fired using the 
+ *  ns3::WifiRemoteStation::m_ssrc trace hook.
+ * 
+ * Finally, we provide access to the per-remote-station SLRC couter that
+ * indications the number of retransmissions of data.  Changes to this 
+ * counter are traced using the ns3::WifiRemoteStation::m_slrc source.
  */
--- a/src/helper/application-container.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/helper/application-container.h	Sun Dec 28 12:34:28 2008 +0000
@@ -41,7 +41,7 @@
   /**
    * Create an ApplicationContainer with exactly one application
    *
-   * \param node a node to add to the container
+   * \param application The application to add to the container
    */
   ApplicationContainer (Ptr<Application> application);
 
--- a/src/helper/on-off-helper.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/helper/on-off-helper.h	Sun Dec 28 12:34:28 2008 +0000
@@ -59,18 +59,27 @@
    *
    * \param c NodeContainer of the set of nodes on which an OnOffApplication 
    * will be installed.
+   * \returns Container of Ptr to the applications installed.
    */
   ApplicationContainer Install (NodeContainer c) const;
 
   /**
-   * Install an ns3::OnOffApplication on each node of the input container
-   * configured with all the attributes set with SetAttribute.
+   * Install an ns3::OnOffApplication on the node configured with all the 
+   * attributes set with SetAttribute.
    *
-   * \param c The node on which an OnOffApplication will be installed.
+   * \param node The node on which an OnOffApplication will be installed.
+   * \returns Container of Ptr to the applications installed.
    */
   ApplicationContainer Install (Ptr<Node> node) const;
 
 private:
+  /**
+   * Install an ns3::OnOffApplication on the node configured with all the 
+   * attributes set with SetAttribute.
+   *
+   * \param node The node on which an OnOffApplication will be installed.
+   * \returns Ptr to the application installed.
+   */
   Ptr<Application> InstallPriv (Ptr<Node> node) const;
   std::string m_protocol;
   Address m_remote;
--- a/src/helper/wifi-helper.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/helper/wifi-helper.h	Sun Dec 28 12:34:28 2008 +0000
@@ -32,10 +32,24 @@
 class WifiNetDevice;
 class Node;
 
+/**
+ * \brief create PHY objects
+ *
+ * This base class must be implemented by new PHY implementation which wish to integrate
+ * with the \ref ns3::WifiHelper class.
+ */
 class WifiPhyHelper
 {
 public:
   virtual ~WifiPhyHelper ();
+  /**
+   * \param node the node on which the PHY object will reside
+   * \param device the device within which the PHY object will reside
+   * \returns a new PHY object.
+   *
+   * Subclasses must implement this method to allow the ns3::WifiHelper class
+   * to create PHY objects from ns3::WifiHelper::Install.
+   */
   virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const = 0;
 };
 
@@ -49,8 +63,18 @@
 class WifiHelper
 {
 public:
+  /**
+   * Create a Wifi helper in an empty state: all its parameters
+   * must be set before calling ns3::WifiHelper::Install
+   */
   WifiHelper ();
 
+  /**
+   * \returns a new WifiHelper in a default state
+   *
+   * The default state is defined as being an Adhoc MAC layer with an ARF rate control algorithm
+   * and both objects using their default attribute values.
+   */
   static WifiHelper Default (void);
 
   /**
@@ -117,7 +141,17 @@
                std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
                std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
 
+  /**
+   * \param phy the PHY helper to create PHY objects
+   * \param c the set of nodes on which a wifi device must be created
+   * \returns a device container which contains all the devices created by this method.
+   */
   NetDeviceContainer Install (const WifiPhyHelper &phy, NodeContainer c) const;
+  /**
+   * \param phy the PHY helper to create PHY objects
+   * \param node the node on which a wifi device must be created
+   * \returns a device container which contains all the devices created by this method.
+   */
   NetDeviceContainer Install (const WifiPhyHelper &phy, Ptr<Node> node) const;
 
 private:
--- a/src/helper/wscript	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/helper/wscript	Sun Dec 28 12:34:28 2008 +0000
@@ -21,7 +21,7 @@
         'ipv4-interface-container.cc',
         'udp-echo-helper.cc',
         'bridge-helper.cc',
-        'yans-wifi-phy-helper.cc',
+        'yans-wifi-helper.cc',
         'v4ping-helper.cc',
         ]
 
@@ -46,7 +46,7 @@
         'ipv4-interface-container.h',
         'udp-echo-helper.h',
         'bridge-helper.h',
-        'yans-wifi-phy-helper.h',
+        'yans-wifi-helper.h',
         'v4ping-helper.h',
         ]
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/yans-wifi-helper.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,305 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 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 <mathieu.lacage@sophia.inria.fr>
+ */
+#include "yans-wifi-helper.h"
+#include "ns3/error-rate-model.h"
+#include "ns3/propagation-loss-model.h"
+#include "ns3/propagation-delay-model.h"
+#include "ns3/yans-wifi-channel.h"
+#include "ns3/yans-wifi-phy.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/simulator.h"
+#include "ns3/config.h"
+
+namespace ns3 {
+
+static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
+                            WifiMode mode, WifiPreamble preamble, 
+                            uint8_t txLevel)
+{
+  writer->WritePacket (packet);
+}
+
+static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
+                            Ptr<const Packet> packet, double snr, WifiMode mode, 
+                            enum WifiPreamble preamble)
+{
+  writer->WritePacket (packet);
+}
+
+static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
+                             Ptr<const Packet> packet,
+                             WifiMode mode, WifiPreamble preamble, 
+                             uint8_t txLevel)
+{
+  *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
+}
+
+static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
+                               Ptr<const Packet> packet, double snr, WifiMode mode, 
+                               enum WifiPreamble preamble)
+{
+  *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
+}
+
+
+YansWifiChannelHelper::YansWifiChannelHelper ()
+{}
+
+YansWifiChannelHelper 
+YansWifiChannelHelper::Default (void)
+{
+  YansWifiChannelHelper helper;
+  helper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+  helper.AddPropagationLoss ("ns3::LogDistancePropagationLossModel");
+  return helper;
+}
+
+void 
+YansWifiChannelHelper::AddPropagationLoss (std::string type,
+					   std::string n0, const AttributeValue &v0,
+					   std::string n1, const AttributeValue &v1,
+					   std::string n2, const AttributeValue &v2,
+					   std::string n3, const AttributeValue &v3,
+					   std::string n4, const AttributeValue &v4,
+					   std::string n5, const AttributeValue &v5,
+					   std::string n6, const AttributeValue &v6,
+					   std::string n7, const AttributeValue &v7)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_propagationLoss.push_back (factory);
+}
+
+void 
+YansWifiChannelHelper::SetPropagationDelay (std::string type,
+					    std::string n0, const AttributeValue &v0,
+					    std::string n1, const AttributeValue &v1,
+					    std::string n2, const AttributeValue &v2,
+					    std::string n3, const AttributeValue &v3,
+					    std::string n4, const AttributeValue &v4,
+					    std::string n5, const AttributeValue &v5,
+					    std::string n6, const AttributeValue &v6,
+					    std::string n7, const AttributeValue &v7)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (type);
+  factory.Set (n0, v0);
+  factory.Set (n1, v1);
+  factory.Set (n2, v2);
+  factory.Set (n3, v3);
+  factory.Set (n4, v4);
+  factory.Set (n5, v5);
+  factory.Set (n6, v6);
+  factory.Set (n7, v7);
+  m_propagationDelay = factory;
+}
+
+Ptr<YansWifiChannel> 
+YansWifiChannelHelper::Create (void) const
+{
+  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
+  Ptr<PropagationLossModel> prev = 0;
+  for (std::vector<ObjectFactory>::const_iterator i = m_propagationLoss.begin (); i != m_propagationLoss.end (); ++i)
+    {
+      Ptr<PropagationLossModel> cur = (*i).Create<PropagationLossModel> ();
+      if (prev != 0)
+	{
+	  prev->SetNext (cur);
+	  prev = cur;
+	}
+      if (m_propagationLoss.begin () == i)
+	{
+	  channel->SetPropagationLossModel (cur);
+	}
+    }
+  Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
+  channel->SetPropagationDelayModel (delay);
+  return channel;
+}
+
+
+YansWifiPhyHelper::YansWifiPhyHelper ()
+  : m_channel (0)
+{
+  m_phy.SetTypeId ("ns3::YansWifiPhy");
+}
+
+YansWifiPhyHelper 
+YansWifiPhyHelper::Default (void)
+{
+  YansWifiPhyHelper helper;
+  helper.SetErrorRateModel ("ns3::ErrorRateModel");
+  return helper;
+}
+
+void 
+YansWifiPhyHelper::SetChannel (Ptr<YansWifiChannel> channel)
+{
+  m_channel = channel;
+}
+void 
+YansWifiPhyHelper::Set (std::string name, const AttributeValue &v)
+{
+  m_phy.Set (name, v);
+}
+
+void 
+YansWifiPhyHelper::SetErrorRateModel (std::string name,
+                                     std::string n0, const AttributeValue &v0,
+                                     std::string n1, const AttributeValue &v1,
+                                     std::string n2, const AttributeValue &v2,
+                                     std::string n3, const AttributeValue &v3,
+                                     std::string n4, const AttributeValue &v4,
+                                     std::string n5, const AttributeValue &v5,
+                                     std::string n6, const AttributeValue &v6,
+                                     std::string n7, const AttributeValue &v7)
+{
+  m_errorRateModel = ObjectFactory ();
+  m_errorRateModel.SetTypeId (name);
+  m_errorRateModel.Set (n0, v0);
+  m_errorRateModel.Set (n1, v1);
+  m_errorRateModel.Set (n2, v2);
+  m_errorRateModel.Set (n3, v3);
+  m_errorRateModel.Set (n4, v4);
+  m_errorRateModel.Set (n5, v5);
+  m_errorRateModel.Set (n6, v6);
+  m_errorRateModel.Set (n7, v7);
+}
+
+
+Ptr<WifiPhy> 
+YansWifiPhyHelper::Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const
+{
+  Ptr<YansWifiPhy> phy = m_phy.Create<YansWifiPhy> ();
+  Ptr<ErrorRateModel> error = m_errorRateModel.Create<ErrorRateModel> ();
+  phy->SetErrorRateModel (error);
+  phy->SetChannel (m_channel);
+  phy->SetMobility (node);
+  phy->SetDevice (device);
+  return phy;
+}
+
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+{
+  std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
+  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+  if (matches.GetN () == 0)
+    {
+      return;
+    }
+  oss.str ("");
+  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
+  // we must fully-qualify the call to Create below because it conflicts
+  // with the locally-defined WifiPhyHelper::Create method.
+  Ptr<PcapWriter> pcap = ::ns3::Create<PcapWriter> ();
+  pcap->Open (oss.str ());
+  pcap->WriteWifiHeader ();
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
+}
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+void
+YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnablePcap (filename, devs);
+}
+
+void
+YansWifiPhyHelper::EnablePcapAll (std::string filename)
+{
+  EnablePcap (filename, NodeContainer::GetGlobal ());
+}
+
+void 
+YansWifiPhyHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
+{
+  Packet::EnablePrinting ();
+  std::ostringstream oss;
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
+  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
+}
+void 
+YansWifiPhyHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+void
+YansWifiPhyHelper::EnableAscii (std::ostream &os, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+        {
+          devs.Add (node->GetDevice (j));
+        }
+    }
+  EnableAscii (os, devs);
+}
+
+void
+YansWifiPhyHelper::EnableAsciiAll (std::ostream &os)
+{
+  EnableAscii (os, NodeContainer::GetGlobal ());
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/yans-wifi-helper.h	Sun Dec 28 12:34:28 2008 +0000
@@ -0,0 +1,289 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 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 <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef YANS_WIFI_HELPER_H
+#define YANS_WIFI_HELPER_H
+
+#include "wifi-helper.h"
+#include "ns3/yans-wifi-channel.h"
+
+namespace ns3 {
+
+/**
+ * \brief manage and create wifi channel objects for the yans model.
+ *
+ * The intent of this class is to make it easy to create a channel object
+ * which implements the yans channel model. The yans channel model is described
+ * in "Yet Another Network Simulator", http://cutebugs.net/files/wns2-yans.pdf
+ */
+class YansWifiChannelHelper
+{
+public:
+  /**
+   * Create a channel helper without any parameter set. The user must set
+   * them all to be able to call Create later.
+   */
+  YansWifiChannelHelper ();
+
+  /**
+   * Create a channel helper in a default working state. By default, we create
+   * a channel model with a propagation delay equal to a constant, the speed of light,
+   * and a propagation loss based on a log distance model with a reference loss of 46.6777 dB
+   * at reference distance of 1m.
+   */
+  static YansWifiChannelHelper Default (void);
+
+  /**
+   * \param name the name of the model to add
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * Add a propagation loss model to the set of currently-configured loss models.
+   * This method is additive to allow you to construct complex propagation loss models
+   * such as a log distance + jakes model, etc.
+   */
+  void AddPropagationLoss (std::string name,
+			   std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+			   std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+			   std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+			   std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+			   std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+			   std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+			   std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+			   std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+  /**
+   * \param name the name of the model to set
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * Configure a propagation delay for this channel.
+   */
+  void SetPropagationDelay (std::string name,
+			    std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+			    std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+			    std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+			    std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+			    std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+			    std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+			    std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+			    std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+  /**
+   * \returns a new channel
+   *
+   * Create a channel based on the configuration parameters set previously.
+   */
+  Ptr<YansWifiChannel> Create (void) const;
+
+private:
+  std::vector<ObjectFactory> m_propagationLoss;
+  ObjectFactory m_propagationDelay;
+};
+
+/**
+ * \brief Make it easy to create and manager PHY objects for the yans model.
+ *
+ * The yans PHY model is described in "Yet Another Network Simulator", 
+ * http://cutebugs.net/files/wns2-yans.pdf
+ *
+ * The Pcap and ascii traces generated by the EnableAscii and EnablePcap methods defined
+ * in this class correspond to PHY-level traces. That is, they capture traffic
+ * at the top of the PHY layer, just below the MAC layer.
+ */
+class YansWifiPhyHelper : public WifiPhyHelper
+{
+public:
+  /**
+   * Create a phy helper without any parameter set. The user must set
+   * them all to be able to call Install later.
+   */
+  YansWifiPhyHelper ();
+
+  /**
+   * Create a phy helper in a default working state.
+   */
+  static YansWifiPhyHelper Default (void);
+
+  /**
+   * \param channel the channel to associate to this helper
+   *
+   * Every PHY created by a call to Install is associated to this channel.
+   */
+  void SetChannel (Ptr<YansWifiChannel> channel);
+  /**
+   * \param name the name of the attribute to set
+   * \param v the value of the attribute
+   *
+   * Set an attribute of the underlying PHY object.
+   */
+  void Set (std::string name, const AttributeValue &v);
+  /**
+   * \param name the name of the error rate model to set.
+   * \param n0 the name of the attribute to set
+   * \param v0 the value of the attribute to set
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   * \param n2 the name of the attribute to set
+   * \param v2 the value of the attribute to set
+   * \param n3 the name of the attribute to set
+   * \param v3 the value of the attribute to set
+   * \param n4 the name of the attribute to set
+   * \param v4 the value of the attribute to set
+   * \param n5 the name of the attribute to set
+   * \param v5 the value of the attribute to set
+   * \param n6 the name of the attribute to set
+   * \param v6 the value of the attribute to set
+   * \param n7 the name of the attribute to set
+   * \param v7 the value of the attribute to set
+   *
+   * Set the error rate model and its attributes to use when Install is called.
+   */
+  void SetErrorRateModel (std::string name,
+                          std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
+                          std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+                          std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+                          std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+                          std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
+                          std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
+                          std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
+                          std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nodeid the id of the node to generate pcap output for.
+   * \param deviceid the id of the device to generate pcap output for.
+   *
+   * Generate a pcap file which contains the link-level data observed
+   * by the specified deviceid within the specified nodeid. The pcap
+   * data is stored in the file prefix-nodeid-deviceid.pcap.
+   *
+   * This method should be invoked after the network topology has 
+   * been fully constructed.
+   */
+  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param d container of devices of type ns3::WifiNetDevice
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::WifiNetDevice type.
+   */
+  static void EnablePcap (std::string filename, NetDeviceContainer d);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param n container of nodes.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in one of the 
+   * input nodes.
+   */
+  static void EnablePcap (std::string filename, NodeContainer n);
+  /**
+   * \param filename filename prefix to use for pcap files.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::WifiNetDevice type
+   */
+  static void EnablePcapAll (std::string filename);
+
+  /**
+   * \param os output stream
+   * \param nodeid the id of the node to generate ascii output for.
+   * \param deviceid the id of the device to generate ascii output for.
+   *
+   * Enable ascii output on the specified deviceid within the
+   * specified nodeid if it is of type ns3::WifiNetDevice and dump 
+   * that to the specified stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
+  /**
+   * \param os output stream
+   * \param d device container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in the input
+   * device container and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+  /**
+   * \param os output stream
+   * \param n node container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and which is located in one
+   * of the input node and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NodeContainer n);
+  /**
+   * \param os output stream
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::WifiNetDevice type and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAsciiAll (std::ostream &os);
+
+private:
+  /**
+   * \param node the node on which we wish to create a wifi PHY
+   * \param device the device within which this PHY will be created
+   * \returns a newly-created PHY object.
+   *
+   * This method implements the pure virtual method defined in \ref ns3::WifiPhyHelper.
+   */
+  virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const;
+
+  ObjectFactory m_phy;
+  ObjectFactory m_errorRateModel;
+  Ptr<YansWifiChannel> m_channel;
+};
+
+} // namespace ns3
+
+#endif /* YANS_WIFI_HELPER_H */
--- a/src/helper/yans-wifi-phy-helper.cc	Sun Dec 07 19:02:55 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,305 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 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 <mathieu.lacage@sophia.inria.fr>
- */
-#include "yans-wifi-phy-helper.h"
-#include "ns3/error-rate-model.h"
-#include "ns3/propagation-loss-model.h"
-#include "ns3/propagation-delay-model.h"
-#include "ns3/yans-wifi-channel.h"
-#include "ns3/yans-wifi-phy.h"
-#include "ns3/wifi-net-device.h"
-#include "ns3/pcap-writer.h"
-#include "ns3/simulator.h"
-#include "ns3/config.h"
-
-namespace ns3 {
-
-static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
-                            WifiMode mode, WifiPreamble preamble, 
-                            uint8_t txLevel)
-{
-  writer->WritePacket (packet);
-}
-
-static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
-                            Ptr<const Packet> packet, double snr, WifiMode mode, 
-                            enum WifiPreamble preamble)
-{
-  writer->WritePacket (packet);
-}
-
-static void AsciiPhyTxEvent (std::ostream *os, std::string context, 
-                             Ptr<const Packet> packet,
-                             WifiMode mode, WifiPreamble preamble, 
-                             uint8_t txLevel)
-{
-  *os << "+ " << Simulator::Now () << " " << context << " " << *packet << std::endl;
-}
-
-static void AsciiPhyRxOkEvent (std::ostream *os, std::string context, 
-                               Ptr<const Packet> packet, double snr, WifiMode mode, 
-                               enum WifiPreamble preamble)
-{
-  *os << "r " << Simulator::Now () << " " << context << " " << *packet << std::endl;
-}
-
-
-YansWifiChannelHelper::YansWifiChannelHelper ()
-{}
-
-YansWifiChannelHelper 
-YansWifiChannelHelper::Default (void)
-{
-  YansWifiChannelHelper helper;
-  helper.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
-  helper.AddPropagationLoss ("ns3::LogDistancePropagationLossModel");
-  return helper;
-}
-
-void 
-YansWifiChannelHelper::AddPropagationLoss (std::string type,
-					   std::string n0, const AttributeValue &v0,
-					   std::string n1, const AttributeValue &v1,
-					   std::string n2, const AttributeValue &v2,
-					   std::string n3, const AttributeValue &v3,
-					   std::string n4, const AttributeValue &v4,
-					   std::string n5, const AttributeValue &v5,
-					   std::string n6, const AttributeValue &v6,
-					   std::string n7, const AttributeValue &v7)
-{
-  ObjectFactory factory;
-  factory.SetTypeId (type);
-  factory.Set (n0, v0);
-  factory.Set (n1, v1);
-  factory.Set (n2, v2);
-  factory.Set (n3, v3);
-  factory.Set (n4, v4);
-  factory.Set (n5, v5);
-  factory.Set (n6, v6);
-  factory.Set (n7, v7);
-  m_propagationLoss.push_back (factory);
-}
-
-void 
-YansWifiChannelHelper::SetPropagationDelay (std::string type,
-					    std::string n0, const AttributeValue &v0,
-					    std::string n1, const AttributeValue &v1,
-					    std::string n2, const AttributeValue &v2,
-					    std::string n3, const AttributeValue &v3,
-					    std::string n4, const AttributeValue &v4,
-					    std::string n5, const AttributeValue &v5,
-					    std::string n6, const AttributeValue &v6,
-					    std::string n7, const AttributeValue &v7)
-{
-  ObjectFactory factory;
-  factory.SetTypeId (type);
-  factory.Set (n0, v0);
-  factory.Set (n1, v1);
-  factory.Set (n2, v2);
-  factory.Set (n3, v3);
-  factory.Set (n4, v4);
-  factory.Set (n5, v5);
-  factory.Set (n6, v6);
-  factory.Set (n7, v7);
-  m_propagationDelay = factory;
-}
-
-Ptr<YansWifiChannel> 
-YansWifiChannelHelper::Create (void) const
-{
-  Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
-  Ptr<PropagationLossModel> prev = 0;
-  for (std::vector<ObjectFactory>::const_iterator i = m_propagationLoss.begin (); i != m_propagationLoss.end (); ++i)
-    {
-      Ptr<PropagationLossModel> cur = (*i).Create<PropagationLossModel> ();
-      if (prev != 0)
-	{
-	  prev->SetNext (cur);
-	  prev = cur;
-	}
-      if (m_propagationLoss.begin () == i)
-	{
-	  channel->SetPropagationLossModel (cur);
-	}
-    }
-  Ptr<PropagationDelayModel> delay = m_propagationDelay.Create<PropagationDelayModel> ();
-  channel->SetPropagationDelayModel (delay);
-  return channel;
-}
-
-
-YansWifiPhyHelper::YansWifiPhyHelper ()
-  : m_channel (0)
-{
-  m_phy.SetTypeId ("ns3::YansWifiPhy");
-}
-
-YansWifiPhyHelper 
-YansWifiPhyHelper::Default (void)
-{
-  YansWifiPhyHelper helper;
-  helper.SetErrorRateModel ("ns3::ErrorRateModel");
-  return helper;
-}
-
-void 
-YansWifiPhyHelper::SetChannel (Ptr<YansWifiChannel> channel)
-{
-  m_channel = channel;
-}
-void 
-YansWifiPhyHelper::Set (std::string name, const AttributeValue &v)
-{
-  m_phy.Set (name, v);
-}
-
-void 
-YansWifiPhyHelper::SetErrorRateModel (std::string name,
-                                     std::string n0, const AttributeValue &v0,
-                                     std::string n1, const AttributeValue &v1,
-                                     std::string n2, const AttributeValue &v2,
-                                     std::string n3, const AttributeValue &v3,
-                                     std::string n4, const AttributeValue &v4,
-                                     std::string n5, const AttributeValue &v5,
-                                     std::string n6, const AttributeValue &v6,
-                                     std::string n7, const AttributeValue &v7)
-{
-  m_errorRateModel = ObjectFactory ();
-  m_errorRateModel.SetTypeId (name);
-  m_errorRateModel.Set (n0, v0);
-  m_errorRateModel.Set (n1, v1);
-  m_errorRateModel.Set (n2, v2);
-  m_errorRateModel.Set (n3, v3);
-  m_errorRateModel.Set (n4, v4);
-  m_errorRateModel.Set (n5, v5);
-  m_errorRateModel.Set (n6, v6);
-  m_errorRateModel.Set (n7, v7);
-}
-
-
-Ptr<WifiPhy> 
-YansWifiPhyHelper::Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const
-{
-  Ptr<YansWifiPhy> phy = m_phy.Create<YansWifiPhy> ();
-  Ptr<ErrorRateModel> error = m_errorRateModel.Create<ErrorRateModel> ();
-  phy->SetErrorRateModel (error);
-  phy->SetChannel (m_channel);
-  phy->SetMobility (node);
-  phy->SetDevice (device);
-  return phy;
-}
-
-void 
-YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
-{
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/";
-  Config::MatchContainer matches = Config::LookupMatches (oss.str ());
-  if (matches.GetN () == 0)
-    {
-      return;
-    }
-  oss.str ("");
-  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
-  // we must fully-qualify the call to Create below because it conflicts
-  // with the locally-defined WifiPhyHelper::Create method.
-  Ptr<PcapWriter> pcap = ::ns3::Create<PcapWriter> ();
-  pcap->Open (oss.str ());
-  pcap->WriteWifiHeader ();
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
-}
-void 
-YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnablePcap (filename, devs);
-}
-
-void
-YansWifiPhyHelper::EnablePcapAll (std::string filename)
-{
-  EnablePcap (filename, NodeContainer::GetGlobal ());
-}
-
-void 
-YansWifiPhyHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
-{
-  Packet::EnablePrinting ();
-  std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyRxOkEvent, &os));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
-  Config::Connect (oss.str (), MakeBoundCallback (&AsciiPhyTxEvent, &os));
-}
-void 
-YansWifiPhyHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
-{
-  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
-    {
-      Ptr<NetDevice> dev = *i;
-      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
-    }
-}
-void
-YansWifiPhyHelper::EnableAscii (std::ostream &os, NodeContainer n)
-{
-  NetDeviceContainer devs;
-  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
-    {
-      Ptr<Node> node = *i;
-      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
-        {
-          devs.Add (node->GetDevice (j));
-        }
-    }
-  EnableAscii (os, devs);
-}
-
-void
-YansWifiPhyHelper::EnableAsciiAll (std::ostream &os)
-{
-  EnableAscii (os, NodeContainer::GetGlobal ());
-}
-
-
-
-} // namespace ns3
--- a/src/helper/yans-wifi-phy-helper.h	Sun Dec 07 19:02:55 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 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 <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef YANS_WIFI_PHY_HELPER_H
-#define YANS_WIFI_PHY_HELPER_H
-
-#include "wifi-helper.h"
-#include "ns3/yans-wifi-channel.h"
-
-namespace ns3 {
-
-class YansWifiChannelHelper
-{
-public:
-  YansWifiChannelHelper ();
-
-  static YansWifiChannelHelper Default (void);
-
-  void AddPropagationLoss (std::string name,
-			   std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-			   std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
-			   std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
-			   std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
-			   std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
-			   std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
-			   std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
-			   std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
-  void SetPropagationDelay (std::string name,
-			    std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-			    std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
-			    std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
-			    std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
-			    std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
-			    std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
-			    std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
-			    std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
-
-  Ptr<YansWifiChannel> Create (void) const;
-
-private:
-  std::vector<ObjectFactory> m_propagationLoss;
-  ObjectFactory m_propagationDelay;
-};
-
-class YansWifiPhyHelper : public WifiPhyHelper
-{
-public:
-  YansWifiPhyHelper ();
-
-  static YansWifiPhyHelper Default (void);
-
-  void SetChannel (Ptr<YansWifiChannel> channel);
-  void Set (std::string name, const AttributeValue &v);
-  void SetErrorRateModel (std::string name,
-                          std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
-                          std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
-                          std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
-                          std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
-                          std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
-                          std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
-                          std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
-                          std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
-
-  virtual Ptr<WifiPhy> Create (Ptr<Node> node, Ptr<WifiNetDevice> device) const;
-
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param nodeid the id of the node to generate pcap output for.
-   * \param deviceid the id of the device to generate pcap output for.
-   *
-   * Generate a pcap file which contains the link-level data observed
-   * by the specified deviceid within the specified nodeid. The pcap
-   * data is stored in the file prefix-nodeid-deviceid.pcap.
-   *
-   * This method should be invoked after the network topology has 
-   * been fully constructed.
-   */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param d container of devices of type ns3::WifiNetDevice
-   *
-   * Enable pcap output on each input device which is of the
-   * ns3::WifiNetDevice type.
-   */
-  static void EnablePcap (std::string filename, NetDeviceContainer d);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   * \param n container of nodes.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one of the 
-   * input nodes.
-   */
-  static void EnablePcap (std::string filename, NodeContainer n);
-  /**
-   * \param filename filename prefix to use for pcap files.
-   *
-   * Enable pcap output on each device which is of the
-   * ns3::WifiNetDevice type
-   */
-  static void EnablePcapAll (std::string filename);
-
-  /**
-   * \param os output stream
-   * \param nodeid the id of the node to generate ascii output for.
-   * \param deviceid the id of the device to generate ascii output for.
-   *
-   * Enable ascii output on the specified deviceid within the
-   * specified nodeid if it is of type ns3::WifiNetDevice and dump 
-   * that to the specified stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
-  /**
-   * \param os output stream
-   * \param d device container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in the input
-   * device container and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
-  /**
-   * \param os output stream
-   * \param n node container
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and which is located in one
-   * of the input node and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAscii (std::ostream &os, NodeContainer n);
-  /**
-   * \param os output stream
-   *
-   * Enable ascii output on each device which is of the
-   * ns3::WifiNetDevice type and dump that to the specified
-   * stdc++ output stream.
-   */
-  static void EnableAsciiAll (std::ostream &os);
-
-private:
-  ObjectFactory m_phy;
-  ObjectFactory m_errorRateModel;
-  Ptr<YansWifiChannel> m_channel;
-};
-
-} // namespace ns3
-
-#endif /* YANS_WIFI_PHY_HELPER_H */
--- a/src/internet-stack/internet-stack.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/internet-stack.h	Sun Dec 28 12:34:28 2008 +0000
@@ -22,6 +22,135 @@
 
 #include "ns3/ptr.h"
 
+/**
+ * \ingroup internetStack
+ * \defgroup internetStackModel Internet Stack Model
+ *
+ * \section internetStackTracingModel Tracing in the Internet Stack
+ *
+ * The internet stack provides a number of trace sources in its various
+ * protocol implementations.  These trace sources can be hooked using your own 
+ * custom trace code, or you can use our helper functions in some cases to 
+ * arrange for tracing to be enabled.
+ *
+ * \subsection internetStackArpTracingModel Tracing in ARP
+ *
+ * ARP provides two trace hooks, one in the cache, and one in the layer three
+ * protocol.  The trace accessor in the cache is given the name "Drop."  When
+ * a packet is transmitted over an interface that requires ARP, it is first
+ * queued for transmission in the ARP cache until the required MAC address is
+ * resolved.  There are a number of retries that may be done trying to get the 
+ * address, and if the maximum retry count is exceeded the packet in question 
+ * is dropped by ARP.  The single trace hook in the ARP cache is called,
+ *
+ * - If an outbound packet is placed in the ARP cache pending address resolution
+ *   and no resolution can be made within the maximum retry count, the outbound 
+ *   packet is dropped and this trace is fired;
+ *
+ * A second trace hook lives in the ARP L3 protocol (also named "Drop") and may 
+ * be called for a  number of reasons.
+ *
+ * - If an ARP reply is received for an entry that is not waiting for a reply,
+ *   the ARP reply packet is dropped and this trace is fired;
+ * - If an ARP reply is received for a non-existant entry, the ARP reply packet 
+ *   is dropped and this trace is fired;
+ * - If an ARP cache entry is in the DEAD state (has timed out) and an ARP reply
+ *   packet is received, the reply packet is dropped and this trace is fired.
+ * - Each ARP cache entry has a queue of pending packets.  If the size of the
+ *   queue is exceeded, the outbound packet is dropped and this trace is fired.
+ *
+ * \subsection internetStackIpv4TracingModel Tracing in IPv4
+ *
+ * The IPv4 layer three protocol provides three trace hooks.  These are the 
+ * "Tx" (ns3::Ipv4L3Protocol::m_txTrace), "Rx" (ns3::Ipv4L3Protocol::m_rxTrace) 
+ * and "Drop" (ns3::Ipv4L3Protocol::m_dropTrace) trace sources.
+ *
+ * The "Tx" trace is fired in a number of situations, all of which indicate that
+ * a given packet is about to be sent down to a given ns3::Ipv4Interface.
+ *
+ * - In the case of a packet destined for the broadcast address, the 
+ *   Ipv4InterfaceList is iterated and for every interface that is up and can
+ *   fragment the packet or has a large enough MTU to transmit the packet,
+ *   the trace is hit.  See ns3::Ipv4L3Protocol::Send.
+ *
+ * - In the case of a packet that needs routing, the "Tx" trace may be fired
+ *   just before a packet is sent to the interface appropriate to the default 
+ *   gateway.  See ns3::Ipv4L3Protocol::SendRealOut.
+ *
+ * - Also in the case of a packet that needs routing, the "Tx" trace may be 
+ *   fired just before a packet is sent to the outgoing interface appropriate
+ *   to the discovered route.  See ns3::Ipv4L3Protocol::SendRealOut.
+ *
+ * The "Rx" trace is fired when a packet is passed from the device up to the
+ * ns3::Ipv4L3Protocol::Receive function.
+ *
+ * - In the receive function, the Ipv4InterfaceList is iterated, and if the
+ *   Ipv4Interface corresponding to the receiving device is fount to be in the
+ *   UP state, the trace is fired.
+ *
+ * The "Drop" trace is fired in any case where the packet is dropped (in both
+ * the transmit and receive paths).
+ *
+ * - In the ns3::Ipv4Interface::Receive function, the packet is dropped and the
+ *   drop trace is hit if the interface corresponding to the receiving device
+ *   is in the DOWN state.
+ *
+ * - Also in the ns3::Ipv4Interface::Receive function, the packet is dropped and
+ *   the drop trace is hit if the checksum is found to be bad.
+ *
+ * - In ns3::Ipv4L3Protocol::Send, an outgoing packet bound for the broadcast
+ *   address is dropped and the "Drop" trace is fired if the "don't fragement"
+ *   bit is set and fragmentation is available and required.
+ *
+ * - Also in ns3::Ipv4L3Protocol::Send, an outgoing packet destined for the 
+ *   broadcast address is dropped and the "Drop" trace is hit if fragmentation
+ *   is not available and is required (MTU < packet size).
+ *
+ * - In the case of a broadcast address, an outgoing packet is cloned for each
+ *   outgoing interface.  If any of the interfaces is in the DOWN state, the 
+ *   "Drop" trace event fires with a reference to the copied packet.
+ *
+ * - In the case of a packet requiring a route, an outgoing packet is dropped
+ *   and the "Drop" trace event fires if no route to the remote host is found.
+ *
+ * - In ns3::Ipv4L3Protocol::SendRealOut, an outgoing packet being routed
+ *   is dropped and the "Drop" trace is fired if the "don't fragement" bit is 
+ *   set and fragmentation is available and required.
+ *
+ * - Also in ns3::Ipv4L3Protocol::SendRealOut, an outgoing packet being routed
+ *   is dropped and the "Drop" trace is hit if fragmentation is not available 
+ *   and is required (MTU < packet size).
+ *
+ * - An outgoing packet being routed is dropped and the "Drop" trace event fires
+ *   if the required Ipv4Interface is in the DOWN state.
+ *
+ * - If a packet is being forwarded, and the TTL is exceeded (see
+ *   ns3::Ipv4L3Protocol::DoForward), the packet is dropped and the "Drop" trace 
+ *   event is fired.
+ *
+ * \subsection internetStackNs3TCPTracingModel Tracing in ns-3 TCP
+ *
+ * There is currently one trace source in the ns-3 TCP implementation named
+ * "CongestionWindow" (see ns3::TcpSocketImpl::m_cWnd).  This is set in a number
+ * of places (see file tcp-socket-impl.cc) whenever the value of the congestion
+ * window is changed.
+ *
+ * \subsection internetStackNscTCPTracingModel Tracing in NSC TCP
+ *
+ * There is currently one trace source in the Network Simulation Cradle TCP 
+ * implementation named "CongestionWindow" (see ns3::NscTcpSocketImpl::m_cWnd).
+ * This is set in a number of places (see file nsc-tcp-socket-impl.cc) when 
+ * the value of the cogestion window is initially set.  Note that this is not
+ * instrumented from the underlying TCP implementaion.
+ *
+ * \subsection internetStackNs3UdpTracingModel Tracing in ns-3 UDP
+ *
+ * There is currently one trace source in the ns-3 UDP implementation named
+ * "Drop" (see ns3::UdpSocketImpl::m_dropTrace).  This is set when a packet
+ * is received in ns3::UdpSocketImpl::ForwardUp and the receive buffer cannot
+ * accomodate the encapsulated data.
+ */
+
 namespace ns3 {
 
 class Node;
--- a/src/internet-stack/ipv4-end-point.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/ipv4-end-point.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -21,6 +21,7 @@
 #include "ipv4-end-point.h"
 #include "ns3/packet.h"
 #include "ns3/log.h"
+#include "ns3/simulator.h"
 
 NS_LOG_COMPONENT_DEFINE ("Ipv4EndPoint");
 
@@ -95,9 +96,14 @@
 Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
 {
   if (!m_rxCallback.IsNull ())
-  {
-    m_rxCallback (p, saddr, sport);
-  }
+    {
+      Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, sport);
+    }
+}
+void 
+Ipv4EndPoint::DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
+{
+  m_rxCallback (p, saddr, sport);
 }
 
 void 
@@ -109,8 +115,16 @@
                    (uint32_t)icmpCode << icmpInfo);
   if (!m_icmpCallback.IsNull ())
     {
-      m_icmpCallback (icmpSource,icmpTtl,icmpType,icmpCode,icmpInfo);
+      Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardIcmp, this, 
+                              icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
     }
 }
+void 
+Ipv4EndPoint::DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, 
+                             uint8_t icmpType, uint8_t icmpCode,
+                             uint32_t icmpInfo)
+{
+  m_icmpCallback (icmpSource,icmpTtl,icmpType,icmpCode,icmpInfo);
+}
 
 }; // namespace ns3
--- a/src/internet-stack/ipv4-end-point.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/ipv4-end-point.h	Sun Dec 28 12:34:28 2008 +0000
@@ -69,6 +69,10 @@
                     uint32_t icmpInfo);
 
 private:
+  void DoForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
+  void DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, 
+                      uint8_t icmpType, uint8_t icmpCode,
+                      uint32_t icmpInfo);
   Ipv4Address m_localAddr;
   uint16_t m_localPort;
   Ipv4Address m_peerAddr;
--- a/src/internet-stack/ipv4-l4-protocol.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/ipv4-l4-protocol.h	Sun Dec 28 12:34:28 2008 +0000
@@ -72,7 +72,7 @@
                                 Ptr<Ipv4Interface> incomingInterface) = 0;
 
   /**
-   * \param icmpSouce the source address of the icmp message
+   * \param icmpSource the source address of the icmp message
    * \param icmpTtl the ttl of the icmp message
    * \param icmpType the 'type' field of the icmp message
    * \param icmpCode the 'code' field of the icmp message
--- a/src/internet-stack/rtt-estimator.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/rtt-estimator.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -51,6 +51,11 @@
                    TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&RttEstimator::est),
                    MakeTimeChecker ())
+    .AddAttribute ("MinRTO", 
+                   "Minimum retransmit timeout value",
+                   TimeValue (Seconds (0.2)),
+                   MakeTimeAccessor (&RttEstimator::minrto),
+                   MakeTimeChecker ())
     ;
   return tid;
 }
@@ -217,9 +222,17 @@
 {
   // If not enough samples, justjust return 2 times estimate   
   //if (nSamples < 2) return est * 2;
+  Time retval;
   if (variance < est / Scalar (4.0))
-    return est * Scalar (2 * multiplier);            // At least twice current est
-  return (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
+    {
+      retval = est * Scalar (2 * multiplier);            // At least twice current est
+    }
+  else
+    {
+      retval = (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
+    }
+  retval = Max (retval, minrto);
+  return retval;
 }
 
 Ptr<RttEstimator> RttMeanDeviation::Copy () const
--- a/src/internet-stack/rtt-estimator.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/rtt-estimator.h	Sun Dec 28 12:34:28 2008 +0000
@@ -76,6 +76,7 @@
   double m_maxMultiplier;
 public:
   Time       est;     // Current estimate
+  Time       minrto; // minimum value of the timeout
   uint32_t      nSamples;// Number of samples
   double       multiplier;   // RTO Multiplier
 };
--- a/src/internet-stack/tcp-socket-impl.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/tcp-socket-impl.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -145,9 +145,19 @@
     {
       m_rtt = sock.m_rtt->Copy();
     }
-  //null out the socket base class recvcallback,
+  //null out the socket base class callbacks,
   //make user of the socket register this explicitly
-  SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > () );
+  Callback<void, Ptr< Socket > > vPS =
+      MakeNullCallback<void, Ptr<Socket> > ();
+  Callback<void, Ptr<Socket>, const Address &> vPSA =
+      MakeNullCallback<void, Ptr<Socket>, const Address &> ();
+  Callback<void, Ptr<Socket>, uint32_t> vPSUI =
+      MakeNullCallback<void, Ptr<Socket>, uint32_t> ();
+
+  SetConnectCallback (vPS, vPS);
+  SetDataSentCallback (vPSUI);
+  SetSendCallback (vPSUI);
+  SetRecvCallback (vPS);
   //can't "copy" the endpoint just yes, must do this when we know the peer info
   //too; this is in SYN_ACK_TX
 }
@@ -473,6 +483,11 @@
   NS_LOG_FUNCTION_NOARGS ();
   if(m_bufferedData.empty())
     {
+      if(m_state == CLOSE_WAIT) //means EOF
+        {
+          return Create<Packet>();
+        }
+      //else, means nothing to read
       return 0;
     }
   UnAckData_t out; //serves as buffer to return up to the user
@@ -547,7 +562,8 @@
 {
   NS_LOG_FUNCTION (this << maxSize << flags);
   Ptr<Packet> packet = Recv (maxSize, flags);
-  if (packet != 0)
+  //Null packet means no data to read, and an empty packet indicates EOF
+  if (packet != 0 && packet->GetSize() != 0)
     {
       SocketAddressTag tag;
       bool found;
--- a/src/internet-stack/udp-l4-protocol.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/internet-stack/udp-l4-protocol.h	Sun Dec 28 12:34:28 2008 +0000
@@ -87,8 +87,19 @@
   virtual enum Ipv4L4Protocol::RxStatus Receive(Ptr<Packet> p, 
                                                 Ipv4Address const &source,
                                                 Ipv4Address const &destination,
-                       Ptr<Ipv4Interface> interface);
+                                                Ptr<Ipv4Interface> interface);
 
+  /**
+   * \brief Receive an ICMP packet
+   * \param icmpSource The IP address of the source of the packet.
+   * \param icmpTtl The time to live from the IP header
+   * \param icmpType The type of the message from the ICMP header
+   * \param icmpCode The message code from the ICMP header
+   * \param icmpInfo 32-bit integer carrying informational value of varying semantics.
+   * \param payloadSource The IP source addresss from the IP header of the packet
+   * \param payloadDestination The IP destination address from the IP header of the packet
+   * \param payload Payload of the ICMP packet
+   */
   virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
                             uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
                             Ipv4Address payloadSource,Ipv4Address payloadDestination,
--- a/src/node/socket.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/node/socket.h	Sun Dec 28 12:34:28 2008 +0000
@@ -214,7 +214,6 @@
     
   /**
    * \brief Listen for incoming connections.
-   * \param queueLimit maximum number of incoming request to queue
    * \returns 0 on success, -1 on error (in which case errno is set).
    */
   virtual int Listen (void) = 0;
--- a/src/routing/global-routing/global-router-interface.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/routing/global-routing/global-router-interface.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -1277,6 +1277,11 @@
   NS_LOG_FUNCTION (nd << allowRecursion);
 
   Ptr<Channel> ch = nd->GetChannel();
+  if (!ch)
+    {
+      // It may be that this net device is a stub device, without a channel
+      return false;
+    }
   uint32_t nDevices = ch->GetNDevices();
   NS_ASSERT (nDevices);
 
--- a/src/routing/olsr/olsr-routing-table.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/routing/olsr/olsr-routing-table.h	Sun Dec 28 12:34:28 2008 +0000
@@ -21,7 +21,7 @@
  */
 
 ///
-/// \file	OLSR_rtable.h
+/// \file	olsr-routing-table.h
 /// \brief	Header file for routing table's related stuff.
 ///
 
--- a/src/simulator/default-simulator-impl.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/default-simulator-impl.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -49,7 +49,6 @@
 DefaultSimulatorImpl::DefaultSimulatorImpl ()
 {
   m_stop = false;
-  m_stopAt = 0;
   // uids are allocated from 4.
   // uid 0 is "invalid" events
   // uid 1 is "now" events
@@ -146,8 +145,7 @@
 DefaultSimulatorImpl::Run (void)
 {
 
-  while (!m_events->IsEmpty () && !m_stop && 
-         (m_stopAt == 0 || m_stopAt > NextTs ())) 
+  while (!m_events->IsEmpty () && !m_stop) 
     {
       ProcessOneEvent ();
     }
@@ -169,13 +167,6 @@
   m_stop = true;
 }
 
-void 
-DefaultSimulatorImpl::Stop (Time const &time)
-{
-  NS_ASSERT (time.IsPositive ());
-  Time absolute = Simulator::Now () + time;
-  m_stopAt = absolute.GetTimeStep ();
-}
 
 //
 // Schedule an event for a _relative_ time in the future.
--- a/src/simulator/default-simulator-impl.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/default-simulator-impl.h	Sun Dec 28 12:34:28 2008 +0000
@@ -45,7 +45,6 @@
   virtual bool IsFinished (void) const;
   virtual Time Next (void) const;
   virtual void Stop (void);
-  virtual void Stop (Time const &time);
   virtual EventId Schedule (Time const &time, EventImpl *event);
   virtual EventId ScheduleNow (EventImpl *event);
   virtual EventId ScheduleDestroy (EventImpl *event);
@@ -66,7 +65,6 @@
 
   typedef std::list<EventId> DestroyEvents;
   DestroyEvents m_destroyEvents;
-  uint64_t m_stopAt;
   bool m_stop;
   Ptr<Scheduler> m_events;
   uint32_t m_uid;
--- a/src/simulator/realtime-simulator-impl.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/realtime-simulator-impl.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -68,7 +68,6 @@
   NS_LOG_FUNCTION_NOARGS ();
 
   m_stop = false;
-  m_stopAt = 0;
   m_running = false;
   // uids are allocated from 4.
   // uid 0 is "invalid" events
@@ -441,16 +440,6 @@
           {
             done = true;
           }
-        //
-        // We also want to stop the simulator at some time even if there are events 
-        // that have been scheduled out in the future.  If we're in realtime mode, we 
-        // actually have time passing, so we must look at the realtime clock to see if 
-        // we're past the end time.
-        //
-        if (m_stopAt && m_stopAt <= m_synchronizer->GetCurrentRealtime ())
-          {
-            done = true;
-          }
       }
 
       if (done)
@@ -539,37 +528,6 @@
   m_stop = true;
 }
 
-static void Placeholder (void) {}
-
-//
-// Schedule a stop for a _relative_ time in the future.  If the simulation
-// hasn't started yet, this will effectively be an absolute time.
-//
-void 
-RealtimeSimulatorImpl::Stop (Time const &time)
-{
-  NS_LOG_FUNCTION (time);
-
-  Time tAbsolute = Simulator::Now () + time;
-  NS_ASSERT (tAbsolute.IsPositive ());
-  NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
-  m_stopAt = tAbsolute.GetTimeStep ();
-
-  //
-  // For the realtime case, we need a real event sitting out at the end of time
-  // to keep the simulator running (sleeping) while there are no other events 
-  // present.  If an "external" device in another thread decides to schedule an
-  // event, the sleeping synchronizer will be awakened and the new event will
-  // be run.
-  //
-  // The easiest thing to do is to call back up into the simulator to take 
-  // advantage of all of the nice event wrappers.  This will call back down into
-  // RealtimeSimulatorImpl::Schedule to do the work.  This path interprets the 
-  // time as relative, so pass the relative time.
-  //
-  Simulator::Schedule (time, &Placeholder);
-}
-
 //
 // Schedule an event for a _relative_ time in the future.
 //
--- a/src/simulator/realtime-simulator-impl.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/realtime-simulator-impl.h	Sun Dec 28 12:34:28 2008 +0000
@@ -55,7 +55,6 @@
   virtual bool IsFinished (void) const;
   virtual Time Next (void) const;
   virtual void Stop (void);
-  virtual void Stop (Time const &time);
   virtual EventId Schedule (Time const &time, EventImpl *event);
   virtual EventId ScheduleNow (EventImpl *event);
   virtual EventId ScheduleDestroy (EventImpl *event);
@@ -89,7 +88,6 @@
 
   typedef std::list<EventId> DestroyEvents;
   DestroyEvents m_destroyEvents;
-  uint64_t m_stopAt;
   bool m_stop;
   bool m_running;
 
--- a/src/simulator/scheduler.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/scheduler.h	Sun Dec 28 12:34:28 2008 +0000
@@ -87,7 +87,7 @@
    */
   virtual Event RemoveNext (void) = 0;
   /**
-   * \param id the id of the event to remove
+   * \param ev the event to remove
    *
    * This methods cannot be invoked if the list is empty.
    */
--- a/src/simulator/simulator-impl.h	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/simulator-impl.h	Sun Dec 28 12:34:28 2008 +0000
@@ -38,7 +38,6 @@
   virtual bool IsFinished (void) const = 0;
   virtual Time Next (void) const = 0;
   virtual void Stop (void) = 0;
-  virtual void Stop (Time const &time) = 0;
   virtual EventId Schedule (Time const &time, EventImpl *event) = 0;
   virtual EventId ScheduleNow (EventImpl *event) = 0;
   virtual EventId ScheduleDestroy (EventImpl *event) = 0;
--- a/src/simulator/simulator.cc	Sun Dec 07 19:02:55 2008 +0000
+++ b/src/simulator/simulator.cc	Sun Dec 28 12:34:28 2008 +0000
@@ -169,7 +169,7 @@
 Simulator::Stop (Time const &time)
 {
   NS_LOG_FUNCTION (time);
-  GetImpl ()->Stop (time);
+  Simulator::Schedule (time, &Simulator::Stop);
 }
 
 Time
--- a/wscript	Sun Dec 07 19:02:55 2008 +0000
+++ b/wscript	Sun Dec 28 12:34:28 2008 +0000
@@ -492,9 +492,11 @@
         if not regression_traces:
             regression_traces = None
         try:
-            regression.run_regression(regression_traces)
+            retval = regression.run_regression(regression_traces)
         finally:
             os.chdir(_dir)
+        if retval:
+            sys.exit(retval)
 
     if Params.g_options.lcov_report:
         lcov_report()