branch merge
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 31 Mar 2008 13:54:41 -0700
changeset 2853 1cff5dd98f63
parent 2852 30000484443d (current diff)
parent 2784 49006cbbfac7 (diff)
child 2854 3d483112bbdf
branch merge
--- a/examples/csma-broadcast.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/examples/csma-broadcast.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -79,16 +79,21 @@
   cmd.Parse (argc, argv);
 
   NS_LOG_INFO ("Create nodes.");
-  NodeContainer c0;
-  c0.Create (2);
-
-  NodeContainer c1;
-  c1.Add (c0.Get (0));
-  c1.Create (1);
-
+  NodeContainer c;
+  c.Create (3);
+  NodeContainer c0 = NodeContainer (c.Get (0), c.Get (1));
+  NodeContainer c1 = NodeContainer (c.Get (0), c.Get (2));
 
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
+  // Also configure some tcpdump traces; each interface will be traced
+  // The output files will be named 
+  // csma-broadcast.pcap-<nodeId>-<interfaceId>
+  // and can be read by the "tcpdump -tt -r" command 
+  csma.EnablePcap ("csma-broadcast.pcap");
+  std::ofstream ascii;
+  ascii.open ("csma-broadcast.tr");
+  csma.EnableAscii (ascii);
   csma.SetChannelParameter ("BitRate", DataRate(5000000));
   csma.SetChannelParameter ("Delay", MilliSeconds(2));
 
@@ -133,20 +138,6 @@
   sink.Build (c1.Get (1));
 
 
-  NS_LOG_INFO ("Configure Tracing.");
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
-  // Trace output will be sent to the csma-broadcast.tr file
-  AsciiTrace asciitrace ("csma-broadcast.tr");
-  asciitrace.TraceAllNetDeviceRx ();
-  asciitrace.TraceAllQueues ();
-
-  // Also configure some tcpdump traces; each interface will be traced
-  // The output files will be named 
-  // simple-point-to-point.pcap-<nodeId>-<interfaceId>
-  // and can be read by the "tcpdump -r" command (use "-tt" option to
-  // display timestamps correctly)
-  PcapTrace pcaptrace ("csma-broadcast.pcap");
-  pcaptrace.TraceAllIp ();
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();    
--- a/examples/simple-global-routing.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/examples/simple-global-routing.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -42,31 +42,11 @@
 #include <string>
 #include <cassert>
 
-#include "ns3/log.h"
-
-#include "ns3/command-line.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/config.h"
-#include "ns3/uinteger.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
 #include "ns3/ascii-trace.h"
 #include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/point-to-point-channel.h"
-#include "ns3/point-to-point-net-device.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/point-to-point-topology.h"
-#include "ns3/onoff-application.h"
-#include "ns3/packet-sink.h"
 #include "ns3/global-route-manager.h"
 
 using namespace ns3;
@@ -118,38 +98,39 @@
   // Here, we will explicitly create four nodes.  In more sophisticated
   // topologies, we could configure a node factory.
   NS_LOG_INFO ("Create nodes.");
-  Ptr<Node> n0 = CreateObject<InternetNode> ();
-  Ptr<Node> n1 = CreateObject<InternetNode> (); 
-  Ptr<Node> n2 = CreateObject<InternetNode> (); 
-  Ptr<Node> n3 = CreateObject<InternetNode> ();
+  NodeContainer c;
+  c.Create (4);
+  NodeContainer n0n2 = NodeContainer (c.Get(0), c.Get (2));
+  NodeContainer n1n2 = NodeContainer (c.Get(1), c.Get (2));
+  NodeContainer n3n2 = NodeContainer (c.Get(3), c.Get (2));
+
+  InternetStackHelper internet;
+  internet.Build (c);
 
   // We create the channels first without any IP addressing information
   NS_LOG_INFO ("Create channels.");
-  Ptr<PointToPointChannel> channel0 = 
-    PointToPointTopology::AddPointToPointLink (
-      n0, n2, DataRate (5000000), MilliSeconds (2));
+  PointToPointHelper p2p;
+  p2p.SetChannelParameter ("BitRate", DataRate (5000000));
+  p2p.SetChannelParameter ("Delay", MilliSeconds (2));
+  NetDeviceContainer d0d2 = p2p.Build (n0n2);
 
-  Ptr<PointToPointChannel> channel1 = 
-    PointToPointTopology::AddPointToPointLink (
-      n1, n2, DataRate (5000000), MilliSeconds (2));
+  NetDeviceContainer d1d2 = p2p.Build (n1n2);
   
-  Ptr<PointToPointChannel> channel2 = 
-    PointToPointTopology::AddPointToPointLink (
-      n2, n3, DataRate (1500000), MilliSeconds (10));
+  p2p.SetChannelParameter ("BitRate", DataRate (1500000));
+  p2p.SetChannelParameter ("Delay", MilliSeconds (10));
+  NetDeviceContainer d3d2 = p2p.Build (n3n2);
   
   // Later, we add IP addresses.  
   NS_LOG_INFO ("Assign IP Addresses.");
-  PointToPointTopology::AddIpv4Addresses (
-      channel0, n0, Ipv4Address ("10.1.1.1"),
-      n2, Ipv4Address ("10.1.1.2"));
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i0i2 = ipv4.Allocate (d0d2);
+
+  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+  Ipv4InterfaceContainer i1i2 = ipv4.Allocate (d1d2);
   
-  PointToPointTopology::AddIpv4Addresses (
-      channel1, n1, Ipv4Address ("10.1.2.1"),
-      n2, Ipv4Address ("10.1.2.2"));
-  
-  PointToPointTopology::AddIpv4Addresses (
-      channel2, n2, Ipv4Address ("10.1.3.1"),
-      n3, Ipv4Address ("10.1.3.2"));
+  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
+  Ipv4InterfaceContainer i3i2 = ipv4.Allocate (d3d2);
 
   // Create router nodes, initialize routing database and set up the routing
   // tables in the nodes.
@@ -159,43 +140,32 @@
   // 210 bytes at a rate of 448 Kb/s
   NS_LOG_INFO ("Create Applications.");
   uint16_t port = 9;   // Discard port (RFC 863)
-  Ptr<OnOffApplication> ooff = 
-    CreateObject<OnOffApplication> ("Remote", Address (InetSocketAddress ("10.1.3.2", port)), 
-                                    "Protocol", TypeId::LookupByName ("ns3::Udp"),
-                                    "OnTime", ConstantVariable (1), 
-                                    "OffTime", ConstantVariable (0));
-  n0->AddApplication (ooff);
-  // Start the application
-  ooff->Start (Seconds (1.0));
-  ooff->Stop (Seconds (10.0));
+  OnOffHelper onoff;
+  onoff.SetAppAttribute ("OnTime", ConstantVariable (1));
+  onoff.SetAppAttribute ("OffTime", ConstantVariable (0));
+  onoff.SetUdpRemote (i3i2.GetAddress (0), port);
+  ApplicationContainer apps = onoff.Build (c.Get (0));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
 
   // Create a packet sink to receive these packets
   // The last argument "true" disables output from the Receive callback
-  Ptr<PacketSink> sink = 
-    CreateObject<PacketSink> ("Remote", Address (InetSocketAddress (Ipv4Address::GetAny (), port)),
-                              "Protocol", TypeId::LookupByName ("ns3::Udp"));
-  n3->AddApplication (sink);
-  // Start the sink
-  sink->Start (Seconds (1.0));
-  sink->Stop (Seconds (10.0));
+  PacketSinkHelper sink;
+  sink.SetupUdp (Ipv4Address::GetAny (), port);
+  apps = sink.Build (c.Get (3));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
-  ooff = CreateObject<OnOffApplication> ("Remote", Address (InetSocketAddress ("10.1.2.1", port)),
-                                         "Protocol", TypeId::LookupByName ("ns3::Udp"),
-                                         "OnTime", ConstantVariable (1), 
-                                         "OffTime", ConstantVariable (0));
-  n3->AddApplication (ooff);
-  // Start the application
-  ooff->Start (Seconds (1.1));
-  ooff->Stop (Seconds (10.0));
+  onoff.SetUdpRemote (i1i2.GetAddress (0), port);
+  apps = onoff.Build (c.Get (3));
+  apps.Start (Seconds (1.1));
+  apps.Stop (Seconds (10.0));
 
   // Create a packet sink to receive these packets
-  sink = CreateObject<PacketSink> ("Remote", Address (InetSocketAddress (Ipv4Address::GetAny (), port)), 
-                                   "Protocol", TypeId::LookupByName ("ns3::Udp"));
-  n1->AddApplication (sink);
-  // Start the sink
-  sink->Start (Seconds (1.1));
-  sink->Stop (Seconds (10.0));
+  apps = sink.Build (c.Get (1));
+  apps.Start (Seconds (1.1));
+  apps.Stop (Seconds (10.0));
 
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
   // Trace output will be sent to the simple-global-routing.tr file
--- a/examples/udp-echo.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/examples/udp-echo.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -25,28 +25,11 @@
 // - DropTail queues 
 // - Tracing of queues and packet receptions to file "udp-echo.tr"
 
-#include "ns3/command-line.h"
-#include "ns3/ptr.h"
-#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
 #include "ns3/ascii-trace.h"
 #include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-channel.h"
-#include "ns3/csma-net-device.h"
-#include "ns3/csma-topology.h"
-#include "ns3/csma-ipv4-topology.h"
-#include "ns3/mac48-address.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/udp-echo-client.h"
-#include "ns3/udp-echo-server.h"
-#include "ns3/uinteger.h"
 
 using namespace ns3;
 
@@ -94,75 +77,40 @@
 // Explicitly create the nodes required by the topology (shown above).
 //
   NS_LOG_INFO ("Create nodes.");
-  Ptr<Node> n0 = CreateObject<InternetNode> ();
-  Ptr<Node> n1 = CreateObject<InternetNode> (); 
-  Ptr<Node> n2 = CreateObject<InternetNode> (); 
-  Ptr<Node> n3 = CreateObject<InternetNode> ();
+  NodeContainer n;
+  n.Create (4);
+
+  InternetStackHelper internet;
+  internet.Build (n);
 
   NS_LOG_INFO ("Create channels.");
 //
 // Explicitly create the channels required by the topology (shown above).
 //
-  Ptr<CsmaChannel> lan = CsmaTopology::CreateCsmaChannel(
-    DataRate(5000000), MilliSeconds(2));
+  CsmaHelper csma;
+  csma.SetChannelParameter ("BitRate", DataRate(5000000));
+  csma.SetChannelParameter ("Delay", MilliSeconds (2));
+  NetDeviceContainer d = csma.Build (n);
 
-  NS_LOG_INFO ("Build Topology.");
-//
-// Now fill out the topology by creating the net devices required to connect
-// the nodes to the channels and hooking them up.  AddIpv4CsmaNetDevice will
-// create a net device, add a MAC address (in memory of the pink flamingo) and
-// connect the net device to a nodes and also to a channel. the 
-// AddIpv4CsmaNetDevice method returns a net device index for the net device
-// created on the node.  Interpret nd0 as the net device we created for node
-// zero.
-//
-  uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan, 
-    Mac48Address("08:00:2e:00:00:00"));
-
-  uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan, 
-    Mac48Address("08:00:2e:00:00:01"));
-
-  uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan, 
-    Mac48Address("08:00:2e:00:00:02"));
-
-  uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan, 
-    Mac48Address("08:00:2e:00:00:03"));
+  Ipv4AddressHelper ipv4;
 //
 // We've got the "hardware" in place.  Now we need to add IP addresses.
 //
   NS_LOG_INFO ("Assign IP Addresses.");
-//
-// XXX BUGBUG
-// Need a better way to get the interface index.  The point-to-point topology
-// as implemented can't return the index since it creates interfaces on both
-// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address).  We need a
-// method on Ipv4 to find the interface index corresponding to a given ipv4 
-// address.
-//
-// Assign IP addresses to the net devices and associated interfaces
-// on the lan.  The AddIpv4Address method returns an Ipv4 interface index
-// which we do not need here.
-//
-  CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address("10.1.1.1"), 
-    Ipv4Mask("255.255.255.0"));
-
-  CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address("10.1.1.2"), 
-    Ipv4Mask("255.255.255.0"));
-
-  CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address("10.1.1.3"), 
-    Ipv4Mask("255.255.255.0"));
-  
-  CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address("10.1.1.4"), 
-    Ipv4Mask("255.255.255.0"));
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Allocate (d);
 
   NS_LOG_INFO ("Create Applications.");
 //
 // Create a UdpEchoServer application on node one.
 //
   uint16_t port = 9;  // well-known echo port number
+  UdpEchoServerHelper server;
+  server.SetPort (port);
+  ApplicationContainer apps = server.Build (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
 
-  Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> ("Port", Uinteger (port));
-  n1->AddApplication (server);
 //
 // Create a UdpEchoClient application to send UDP datagrams from node zero to
 // node one.
@@ -170,22 +118,15 @@
   uint32_t packetSize = 1024;
   uint32_t maxPacketCount = 1;
   Time interPacketInterval = Seconds (1.);
+  UdpEchoClientHelper client;
+  client.SetRemote (i.GetAddress (1), port);
+  client.SetAppAttribute ("MaxPackets", Uinteger (maxPacketCount));
+  client.SetAppAttribute ("Interval", interPacketInterval);
+  client.SetAppAttribute ("PacketSize", Uinteger (packetSize));
+  apps = client.Build (n.Get (0));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
 
-  Ptr<UdpEchoClient> client = 
-    CreateObject<UdpEchoClient> ("RemoteIpv4", Ipv4Address ("10.1.1.2"),
-                                 "RemotePort", Uinteger (port),
-                                 "MaxPackets", Uinteger (maxPacketCount), 
-                                 "Interval", interPacketInterval, 
-                                 "PacketSize", Uinteger (packetSize));
-  n0->AddApplication (client);
-//
-// Tell the applications when to start and stop.
-//
-  server->Start(Seconds(1.));
-  client->Start(Seconds(2.));
-
-  server->Stop (Seconds(10.));
-  client->Stop (Seconds(10.));
 //
 // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
 // Trace output will be sent to the file "udp-echo.tr"
--- a/examples/wifi-adhoc.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/examples/wifi-adhoc.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -225,7 +225,6 @@
   gnuplot.GenerateOutput (std::cout);
 
 
-
   gnuplot = Gnuplot ("rate-control.png");
   Config::SetDefault ("ns3::WifiPhy::Standard", String ("holland"));
 
--- a/src/applications/udp-echo/udp-echo-client.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -74,6 +74,13 @@
   NS_LOG_FUNCTION;
 }
 
+void 
+UdpEchoClient::SetRemote (Ipv4Address ip, uint16_t port)
+{
+  m_peerAddress = ip;
+  m_peerPort = port;
+}
+
 void
 UdpEchoClient::DoDispose (void)
 {
--- a/src/applications/udp-echo/udp-echo-client.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.h	Mon Mar 31 13:54:41 2008 -0700
@@ -22,10 +22,10 @@
 #include "ns3/application.h"
 #include "ns3/event-id.h"
 #include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
 
 namespace ns3 {
 
-class Address;
 class Socket;
 class Packet;
 
@@ -38,6 +38,8 @@
 
   virtual ~UdpEchoClient ();
 
+  void SetRemote (Ipv4Address ip, uint16_t port);
+
 protected:
   virtual void DoDispose (void);
 
--- a/src/applications/udp-echo/udp-echo-server.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -39,8 +39,8 @@
   static TypeId tid = TypeId ("ns3::UdpEchoServer")
     .SetParent<Application> ()
     .AddConstructor<UdpEchoServer> ()
-    .AddAttribute ("Port", "Client Port",
-                   Uinteger (0),
+    .AddAttribute ("Port", "Port on which we listen for incoming packets.",
+                   Uinteger (9),
                    MakeUintegerAccessor (&UdpEchoServer::m_port),
                    MakeUintegerChecker<uint16_t> ())
     ;
--- a/src/applications/udp-echo/udp-echo-server.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-server.h	Mon Mar 31 13:54:41 2008 -0700
@@ -22,10 +22,10 @@
 #include "ns3/application.h"
 #include "ns3/event-id.h"
 #include "ns3/ptr.h"
+#include "ns3/address.h"
 
 namespace ns3 {
 
-class Address;
 class Socket;
 class Packet;
 
--- a/src/common/pcap-writer.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/common/pcap-writer.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -120,4 +120,4 @@
   WriteData((uint8_t*)&data, 2);
 }
 
-}; // namespace ns3
+} // namespace ns3
--- a/src/common/pcap-writer.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/common/pcap-writer.h	Mon Mar 31 13:54:41 2008 -0700
@@ -22,8 +22,8 @@
 #ifndef PCAP_WRITER_H
 #define PCAP_WRITER_H
 
-#include "ns3/callback.h"
 #include <stdint.h>
+#include "ns3/ref-count-base.h"
 
 namespace ns3 {
 
@@ -35,7 +35,8 @@
  * Log Packets to a file in pcap format which can be
  * read by pcap readers.
  */
-class PcapWriter {
+class PcapWriter : public RefCountBase
+{
 public:
   PcapWriter ();
   ~PcapWriter ();
@@ -71,9 +72,8 @@
   void Write16 (uint16_t data);
   void WriteHeader (uint32_t network);
   std::ofstream *m_writer;
-  Callback<void,uint8_t *,uint32_t> m_writeCallback;
 };
 
-}; // namespace ns3
+} // namespace ns3
 
 #endif /* PCAP_WRITER_H */
--- a/src/core/random-variable.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/core/random-variable.h	Mon Mar 31 13:54:41 2008 -0700
@@ -48,7 +48,7 @@
  * the University of Montreal.
  * 
  * NS-3 has a rich set of  random number generators.
- * Class RandomVariableBase defines the base class functionalty
+ * Class RandomVariable defines the base class functionalty
  * required for all random number generators.  By default, the underlying
  * generator is seeded with the time of day, and then deterministically
  * creates a sequence of seeds for each subsequent generator that is created.
@@ -93,7 +93,7 @@
    * generator is seeded with data from /dev/random instead of
    * being seeded based upon the time of day.  For this to be effective,
    * it must be called before the creation of the first instance of a 
-   * RandomVariableBase or subclass.  Example:
+   * RandomVariable or subclass.  Example:
    * \code
    * RandomVariable::UseDevRandom();
    * UniformVariable x(2,3);  //these are seeded randomly
@@ -221,19 +221,19 @@
  * \brief A random variable that returns a constant
  * \ingroup randomvariable
  *
- * Class ConstantVariableImpl defines a random number generator that
+ * Class ConstantVariable defines a random number generator that
  * returns the same value every sample.
  */
 class ConstantVariable : public RandomVariable { 
 
 public:
   /**
-   * Construct a ConstantVariableImpl RNG that returns zero every sample
+   * Construct a ConstantVariable RNG that returns zero every sample
    */
   ConstantVariable();
   
   /**
-   * Construct a ConstantVariableImpl RNG that returns the specified value
+   * Construct a ConstantVariable RNG that returns the specified value
    * every sample.
    * \param c Unchanging value for this RNG.
    */
@@ -260,10 +260,10 @@
 {
 public:
   /**
-   * \brief Constructor for the SequentialVariableImpl RNG.
+   * \brief Constructor for the SequentialVariable RNG.
    *
    * The four parameters define the sequence.  For example
-   * SequentialVariableImpl(0,5,1,2) creates a RNG that has the sequence
+   * SequentialVariable(0,5,1,2) creates a RNG that has the sequence
    * 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 0, 0 ...
    * \param f First value of the sequence.
    * \param l One more than the last value of the sequence.
@@ -273,13 +273,13 @@
   SequentialVariable(double f, double l, double i = 1, uint32_t c = 1);
 
   /**
-   * \brief Constructor for the SequentialVariableImpl RNG.
+   * \brief Constructor for the SequentialVariable RNG.
    *
    * Differs from the first only in that the increment parameter is a
    * random variable
    * \param f First value of the sequence.
    * \param l One more than the last value of the sequence.
-   * \param i Reference to a RandomVariableBase for the sequence increment
+   * \param i Reference to a RandomVariable for the sequence increment
    * \param c Number of times each member of the sequence is repeated
    */
   SequentialVariable(double f, double l, const RandomVariable& i, uint32_t c = 1);
@@ -303,10 +303,10 @@
  * \f$ \left\{ \begin{array}{cl} \alpha  e^{-\alpha x} & x < bound \\ bound & x > bound \end{array}\right. \f$
  * 
  * \code
- * ExponentialVariableImpl x(3.14);
+ * ExponentialVariable x(3.14);
  * x.GetValue();  //will always return with mean 3.14
- * ExponentialVariableImpl::GetSingleValue(20.1); //returns with mean 20.1
- * ExponentialVariableImpl::GetSingleValue(108); //returns with mean 108
+ * ExponentialVariable::GetSingleValue(20.1); //returns with mean 20.1
+ * ExponentialVariable::GetSingleValue(108); //returns with mean 108
  * \endcode
  *
  */
@@ -347,7 +347,7 @@
 };
 
 /**
- * \brief ParetoVariableImpl distributed random var
+ * \brief ParetoVariable distributed random var
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
@@ -362,10 +362,10 @@
  * with the equation \f$ x_m = mean \frac{k-1}{k},  k > 1\f$.
  *
  * \code
- * ParetoVariableImpl x(3.14);
+ * ParetoVariable x(3.14);
  * x.GetValue();  //will always return with mean 3.14
- * ParetoVariableImpl::GetSingleValue(20.1); //returns with mean 20.1
- * ParetoVariableImpl::GetSingleValue(108); //returns with mean 108
+ * ParetoVariable::GetSingleValue(20.1); //returns with mean 20.1
+ * ParetoVariable::GetSingleValue(108); //returns with mean 108
  * \endcode
  */
 class ParetoVariable : public RandomVariable
@@ -419,7 +419,7 @@
 };
 
 /**
- * \brief WeibullVariableImpl distributed random var
+ * \brief WeibullVariable distributed random var
  * \ingroup randomvariable
  *
  * This class supports the creation of objects that return random numbers
@@ -459,7 +459,7 @@
    /**
    * \brief Constructs a weibull random variable with the specified mean
    * \brief value, shape (alpha), and upper bound.
-   * Since WeibullVariableImpl distributions can theoretically return unbounded values,
+   * Since WeibullVariable distributions can theoretically return unbounded values,
    * it is sometimes usefull to specify a fixed upper limit.  Note however
    * that when the upper limit is specified, the true mean of the distribution
    * is slightly smaller than the mean value specified.
@@ -478,7 +478,7 @@
 };
 
 /**
- * \brief Class NormalVariableImpl defines a random variable with a
+ * \brief Class NormalVariable defines a random variable with a
  * normal (Gaussian) distribution.
  * \ingroup randomvariable
  * 
@@ -505,20 +505,20 @@
    * \brief Construct a normal random variable with specified mean and variance
    * \param m Mean value
    * \param v Variance
-   * \param b Bound.  The NormalVariableImpl is bounded within +-bound.
+   * \param b Bound.  The NormalVariable is bounded within +-bound.
    */ 
   NormalVariable(double m, double v, double b = INFINITE_VALUE);
   /**
    * \param m Mean value
    * \param v Variance
-   * \param b Bound.  The NormalVariableImpl is bounded within +-bound.
+   * \param b Bound.  The NormalVariable is bounded within +-bound.
    * \return A random number from a distribution specified by m,v, and b.
    */ 
   static double GetSingleValue(double m, double v, double b = INFINITE_VALUE);
 };
 
 /**
- * \brief EmpiricalVariableImpl distribution random var
+ * \brief EmpiricalVariable distribution random var
  * \ingroup randomvariable
  *
  * Defines a random variable  that has a specified, empirical 
@@ -528,12 +528,14 @@
  * the specified value.  When values are requested,
  * a uniform random variable is used to select a probabililty,
  * and the return value is interpreted linerarly between the
- * two appropriate points in the CDF
+ * two appropriate points in the CDF.  The method is known
+ * as inverse transform sampling:
+ * (http://en.wikipedia.org/wiki/Inverse_transform_sampling).
  */
 class EmpiricalVariable : public RandomVariable {
 public:
   /**
-   * Constructor for the EmpiricalVariableImpl random variables.
+   * Constructor for the EmpiricalVariable random variables.
    */
   explicit EmpiricalVariable();
 
@@ -552,8 +554,9 @@
  * \ingroup randomvariable
  *
  * Defines an empirical distribution where all values are integers.
- * Indentical to EmpiricalVariableImpl, but with slightly different
- * interpolation between points.
+ * Indentical to EmpiricalVariable, except that the inverse transform
+ * sampling interpolation described in the EmpiricalVariable documentation
+ * is modified to only return integers.
  */
 class IntEmpiricalVariable : public EmpiricalVariable 
 {
@@ -580,7 +583,7 @@
    * on successive calls to ::Value().  Note that the d pointer is copied
    * for use by the generator (shallow-copy), not its contents, so the 
    * contents of the array d points to have to remain unchanged for the use 
-   * of DeterministicVariableImpl to be meaningful.
+   * of DeterministicVariable to be meaningful.
    * \param d Pointer to array of random values to return in sequence
    * \param c Number of values in the array
    */
@@ -592,7 +595,7 @@
  * \brief Log-normal Distributed random var
  * \ingroup randomvariable
  *
- * LogNormalVariableImpl defines a random variable with log-normal
+ * LogNormalVariable defines a random variable with log-normal
  * distribution.  If one takes the natural logarithm of random
  * variable following the log-normal distribution, the obtained values
  * follow a normal distribution.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ref-count-base.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -0,0 +1,37 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * 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:  George Riley <riley@ece.gatech.edu>
+ * Adapted from original code in object.h by:
+ * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ref-count-base.h"
+
+namespace ns3 {
+
+RefCountBase::RefCountBase() 
+  : m_count (1) 
+{
+}
+
+RefCountBase::~RefCountBase () 
+{
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/ref-count-base.h	Mon Mar 31 13:54:41 2008 -0700
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * 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:  George Riley <riley@ece.gatech.edu>
+ * Adapted from original code in object.h by:
+ * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef __REF_COUNT_BASE_H__
+#define __REF_COUNT_BASE_H__
+
+#include <stdint.h>
+
+namespace ns3 {
+
+/**
+ * \brief a base class that provides implementations of reference counting
+ *    operations.
+ *  
+ * A base class that provides implementations of reference counting 
+ * operations, for classes that wish to use the templatized smart 
+ * pointer for memory management but that do not wish to derive from
+ * class ns3::Object.
+ *
+ */
+class RefCountBase 
+{ 
+public:
+  RefCountBase();
+  virtual ~RefCountBase ();
+  /**
+   * Increment the reference count. This method should not be called
+   * by user code. RefCountBase instances are expected to be used in
+   * conjunction with the Ptr template which would make calling Ref
+   * unecessary and dangerous.
+   */
+  inline void Ref () const;
+  /**
+   * Decrement the reference count. This method should not be called
+   * by user code. RefCountBase instances are expected to be used in 
+   * conjunction with the Ptr template which would make calling Ref
+   * unecessary and dangerous.
+   */
+  inline void Unref () const;
+private:
+  // Note we make this mutable so that the const methods can still
+  // change it.
+  mutable uint32_t m_count;  // Reference count
+};
+
+} // namespace ns3
+
+namespace ns3 {
+
+// Implementation of the in-line methods
+void
+RefCountBase::Ref () const
+{
+  m_count++;
+}
+
+void
+RefCountBase::Unref () const
+{
+  if (--m_count == 0)
+    { // All references removed, ok to delete
+      delete this;
+    }
+}
+
+} // namespace ns3
+
+#endif /* __REF_COUNT_BASE_H__*/
--- a/src/core/traced-callback.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/core/traced-callback.h	Mon Mar 31 13:54:41 2008 -0700
@@ -28,11 +28,14 @@
 namespace ns3 {
 
 /**
- * \brief log arbitrary number of parameters to a matching ns3::Callback
+ * \brief forward calls to a chain of Callback
  * \ingroup tracing
  *
- * Whenever operator () is invoked on this class, the call and its arguments
- * are forwarded to the internal matching ns3::Callback.
+ * An ns3::TracedCallback has almost exactly the same API as a normal ns3::Callback but
+ * instead of forwarding calls to a single function (as an ns3::Callback normally does),
+ * it forwards calls to a chain of ns3::Callback. TracedCallback::Connect adds a ns3::Callback
+ * at the end of the chain of callbacks. TracedCallback::Disconnect removes a ns3::Callback from
+ * the chain of callbacks.
  */
 template<typename T1 = empty, typename T2 = empty, 
          typename T3 = empty, typename T4 = empty>
@@ -40,9 +43,39 @@
 {
 public:
   TracedCallback ();
+  /**
+   * \param callback callback to add to chain of callbacks
+   *
+   * Append the input callback to the end of the internal list 
+   * of ns3::Callback.
+   */
   void ConnectWithoutContext (const CallbackBase & callback);
+  /**
+   * \param callback callback to add to chain of callbacks
+   * \param path the path to send back to the user callback.
+   *
+   * Append the input callback to the end of the internal list 
+   * of ns3::Callback. This method also will make sure that the
+   * input path specified by the user will be give back to the
+   * user's callback as its first argument. 
+   */
   void Connect (const CallbackBase & callback, std::string path);
+  /**
+   * \param callback callback to remove from the chain of callbacks.
+   *
+   * Remove the input callback from the internal list 
+   * of ns3::Callback. This method is really the symmetric
+   * of the TracedCallback::ConnectWithoutContext method.
+   */
   void DisconnectWithoutContext (const CallbackBase & callback);
+  /**
+   * \param callback callback to remove from the chain of callbacks.
+   * \param path the path which is sent back to the user callback.
+   *
+   * Remove the input callback which has a matching path as first argument 
+   * from the internal list of ns3::Callback. This method is really the symmetric
+   * of the TracedCallback::Connect method.
+   */
   void Disconnect (const CallbackBase & callback, std::string path);
   void operator() (void) const;
   void operator() (T1 a1) const;
--- a/src/core/wscript	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/core/wscript	Mon Mar 31 13:54:41 2008 -0700
@@ -34,6 +34,7 @@
         'type-id.cc',
         'attribute-list.cc',
         'object-base.cc',
+        'ref-count-base.cc',
         'ptr.cc',
         'object.cc',
         'test.cc',
@@ -75,6 +76,7 @@
         'empty.h',
         'callback.h',
         'object-base.h',
+        'ref-count-base.h',
         'type-id.h',
         'attribute-list.h',
         'ptr.h',
--- a/src/devices/csma/csma-net-device.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/csma/csma-net-device.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -200,6 +200,7 @@
       lengthType = protocolNumber;
       break;
     case LLC: {
+      lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
       LlcSnapHeader llc;
       llc.SetType (protocolNumber);
       p->AddHeader (llc);
@@ -441,6 +442,8 @@
       return;
     }
 
+  m_rxTrace (packet);
+
   if (m_encapMode == RAW)
     {
       m_rxCallback (this, packet, 0, GetBroadcast ());
@@ -490,7 +493,6 @@
     }
   else
     {
-      m_rxTrace (packet);
 //
 // protocol must be initialized to avoid a compiler warning in the RAW
 // case that breaks the optimized build.
--- a/src/devices/wifi/amrr-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -89,31 +89,31 @@
 {}
 
 void 
-AmrrWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+AmrrWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
 void 
-AmrrWifiRemoteStation::ReportRtsFailed (void)
+AmrrWifiRemoteStation::DoReportRtsFailed (void)
 {}
 void 
-AmrrWifiRemoteStation::ReportDataFailed (void)
+AmrrWifiRemoteStation::DoReportDataFailed (void)
 {
   m_retry++;
   m_tx_retr++;
 }
 void 
-AmrrWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+AmrrWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {}
 void 
-AmrrWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+AmrrWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   m_retry = 0;
   m_tx_ok++;
 }
 void 
-AmrrWifiRemoteStation::ReportFinalRtsFailed (void)
+AmrrWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-AmrrWifiRemoteStation::ReportFinalDataFailed (void)
+AmrrWifiRemoteStation::DoReportFinalDataFailed (void)
 {
   m_retry = 0;
   m_tx_err++;
--- a/src/devices/wifi/amrr-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/amrr-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -52,13 +52,14 @@
 
   virtual ~AmrrWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/arf-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/arf-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -88,7 +88,7 @@
 
 
 void 
-ArfWifiRemoteStation::ReportRtsFailed (void)
+ArfWifiRemoteStation::DoReportRtsFailed (void)
 {}
 /**
  * It is important to realize that "recovery" mode starts after failure of
@@ -100,7 +100,7 @@
  * transmission, be it an initial transmission or a retransmission.
  */
 void 
-ArfWifiRemoteStation::ReportDataFailed (void)
+ArfWifiRemoteStation::DoReportDataFailed (void)
 {
   m_timer++;
   m_failed++;
@@ -138,13 +138,13 @@
     }
 }
 void 
-ArfWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+ArfWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
-void ArfWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+void ArfWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {
   NS_LOG_DEBUG ("self="<<this<<" rts ok");
 }
-void ArfWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+void ArfWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   m_timer++;
   m_success++;
@@ -164,10 +164,10 @@
     }
 }
 void 
-ArfWifiRemoteStation::ReportFinalRtsFailed (void)
+ArfWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-ArfWifiRemoteStation::ReportFinalDataFailed (void)
+ArfWifiRemoteStation::DoReportFinalDataFailed (void)
 {}
 
 WifiMode
--- a/src/devices/wifi/arf-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/arf-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -60,13 +60,14 @@
                         int minSuccessThreshold);
   virtual ~ArfWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/constant-rate-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/constant-rate-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -32,25 +32,25 @@
 {}
 
 void 
-ConstantRateWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+ConstantRateWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportRtsFailed (void)
+ConstantRateWifiRemoteStation::DoReportRtsFailed (void)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportDataFailed (void)
+ConstantRateWifiRemoteStation::DoReportDataFailed (void)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+ConstantRateWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+ConstantRateWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportFinalRtsFailed (void)
+ConstantRateWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-ConstantRateWifiRemoteStation::ReportFinalDataFailed (void)
+ConstantRateWifiRemoteStation::DoReportFinalDataFailed (void)
 {}
 
 WifiMode 
--- a/src/devices/wifi/constant-rate-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/constant-rate-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -55,13 +55,14 @@
   ConstantRateWifiRemoteStation (Ptr<ConstantRateWifiManager> stations);
   virtual ~ConstantRateWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/dca-txop.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/dca-txop.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -24,7 +24,6 @@
 #include "ns3/simulator.h"
 #include "ns3/node.h"
 #include "ns3/uinteger.h"
-#include "ns3/trace-source-accessor.h"
 
 #include "dca-txop.h"
 #include "dcf-manager.h"
@@ -115,20 +114,13 @@
                    MakeUintegerAccessor (&DcaTxop::SetAifsn,
                                          &DcaTxop::GetAifsn),
                    MakeUintegerChecker<uint32_t> ())
-    .AddTraceSource ("Ssrc", "XXX",
-                     MakeTraceSourceAccessor (&DcaTxop::m_ssrc))
-    .AddTraceSource ("Slrc", "XXX",
-                     MakeTraceSourceAccessor (&DcaTxop::m_slrc))
     ;
   return tid;
 }
 
 DcaTxop::DcaTxop ()
   : m_manager (0),
-    m_currentPacket (0),
-    m_ssrc (0),
-    m_slrc (0)
-
+    m_currentPacket (0)
 {
   m_transmissionListener = new DcaTxop::TransmissionListener (this);
   m_dcf = new DcaTxop::Dcf (this);
@@ -279,6 +271,19 @@
 }
 
 bool
+DcaTxop::NeedRtsRetransmission (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedRtsRetransmission (m_currentPacket);
+}
+
+bool
+DcaTxop::NeedDataRetransmission (void)
+{
+  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
+  return station->NeedDataRetransmission (m_currentPacket);
+}
+bool
 DcaTxop::NeedFragmentation (void)
 {
   WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
@@ -337,19 +342,6 @@
   return fragment;
 }
 
-uint32_t
-DcaTxop::GetMaxSsrc (void) const
-{
-  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
-  return station->GetMaxSsrc (m_currentPacket);
-}
-uint32_t
-DcaTxop::GetMaxSlrc (void) const
-{
-  WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
-  return station->GetMaxSlrc (m_currentPacket);
-}
-
 bool 
 DcaTxop::NeedsAccess (void) const
 {
@@ -372,8 +364,6 @@
       m_currentHdr.SetFragmentNumber (0);
       m_currentHdr.SetNoMoreFragments ();
       m_currentHdr.SetNoRetry ();
-      m_ssrc = 0;
-      m_slrc = 0;
       m_fragmentNumber = 0;
       MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
                     ", to="<<m_currentHdr.GetAddr1 ()<<
@@ -453,15 +443,14 @@
 DcaTxop::GotCts (double snr, WifiMode txMode)
 {
   MY_DEBUG ("got cts");
-  m_ssrc = 0;
 }
 void 
 DcaTxop::MissedCts (void)
 {
   MY_DEBUG ("missed cts");
-  m_ssrc++;
-  if (m_ssrc > GetMaxSsrc ()) 
+  if (!NeedRtsRetransmission ())
     {
+      MY_DEBUG ("Cts Fail");
       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       station->ReportFinalRtsFailed ();
       // to reset the dcf.
@@ -478,7 +467,6 @@
 void 
 DcaTxop::GotAck (double snr, WifiMode txMode)
 {
-  m_slrc = 0;
   if (!NeedFragmentation () ||
       IsLastFragment ()) 
     {
@@ -505,9 +493,9 @@
 DcaTxop::MissedAck (void)
 {
   MY_DEBUG ("missed ack");
-  m_slrc++;
-  if (m_slrc > GetMaxSlrc ()) 
+  if (!NeedDataRetransmission ()) 
     {
+      MY_DEBUG ("Ack Fail");
       WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
       station->ReportFinalDataFailed ();
       // to reset the dcf.    
@@ -516,6 +504,7 @@
     } 
   else 
     {
+      MY_DEBUG ("Retransmit");
       m_currentHdr.SetRetry ();
       if (!m_txFailedCallback.IsNull ()) 
         {
--- a/src/devices/wifi/dca-txop.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/dca-txop.h	Mon Mar 31 13:54:41 2008 -0700
@@ -26,7 +26,6 @@
 #include "ns3/packet.h"
 #include "ns3/nstime.h"
 #include "ns3/object.h"
-#include "ns3/traced-value.h"
 #include "wifi-mac-header.h"
 #include "wifi-mode.h"
 #include "wifi-remote-station-manager.h"
@@ -114,6 +113,7 @@
   class Dcf;
   friend class Dcf;
   friend class TransmissionListener;
+  friend class WifiRemoteStation;
 
   // Inherited from ns3::Object
   Ptr<MacLow> Low (void);
@@ -134,13 +134,13 @@
   void RestartAccessIfNeeded (void);
   void StartAccessIfNeeded (void);
   bool NeedRts (void);
+  bool NeedRtsRetransmission (void);
+  bool NeedDataRetransmission (void);
   bool NeedFragmentation (void);
   uint32_t GetNFragments (void);
   uint32_t GetNextFragmentSize (void);
   uint32_t GetFragmentSize (void);
   WifiRemoteStation *GetStation (Mac48Address to) const;
-  uint32_t GetMaxSsrc (void) const;
-  uint32_t GetMaxSlrc (void) const;
   bool IsLastFragment (void);
   void NextFragment (void);
   Ptr<Packet> GetFragmentPacket (WifiMacHeader *hdr);
@@ -161,8 +161,6 @@
   bool m_accessOngoing;
   Ptr<const Packet> m_currentPacket;
   WifiMacHeader m_currentHdr;
-  TracedValue<uint32_t> m_ssrc;
-  TracedValue<uint32_t> m_slrc;
   uint8_t m_fragmentNumber;
 };
 
--- a/src/devices/wifi/ideal-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/ideal-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -104,31 +104,31 @@
 IdealWifiRemoteStation::~IdealWifiRemoteStation ()
 {}
 void 
-IdealWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+IdealWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
 void 
-IdealWifiRemoteStation::ReportRtsFailed (void)
+IdealWifiRemoteStation::DoReportRtsFailed (void)
 {}
 void 
-IdealWifiRemoteStation::ReportDataFailed (void)
+IdealWifiRemoteStation::DoReportDataFailed (void)
 {}
 void 
-IdealWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+IdealWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {
   TRACE ("got cts for rts snr="<<rtsSnr);
   m_lastSnr = rtsSnr;
 }
 void 
-IdealWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+IdealWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   TRACE ("got cts for rts snr="<<dataSnr);
   m_lastSnr = dataSnr;
 }
 void 
-IdealWifiRemoteStation::ReportFinalRtsFailed (void)
+IdealWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-IdealWifiRemoteStation::ReportFinalDataFailed (void)
+IdealWifiRemoteStation::DoReportFinalDataFailed (void)
 {}
 
 WifiMode
--- a/src/devices/wifi/ideal-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/ideal-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -73,13 +73,14 @@
 
   virtual ~IdealWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/onoe-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -75,35 +75,35 @@
 {}
 
 void 
-OnoeWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+OnoeWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
 void 
-OnoeWifiRemoteStation::ReportRtsFailed (void)
+OnoeWifiRemoteStation::DoReportRtsFailed (void)
 {
   m_shortRetry++;
 }
 void 
-OnoeWifiRemoteStation::ReportDataFailed (void)
+OnoeWifiRemoteStation::DoReportDataFailed (void)
 {
   m_longRetry++;
 }
 void 
-OnoeWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+OnoeWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {}
 void 
-OnoeWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+OnoeWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   UpdateRetry ();
   m_tx_ok++;
 }
 void 
-OnoeWifiRemoteStation::ReportFinalRtsFailed (void)
+OnoeWifiRemoteStation::DoReportFinalRtsFailed (void)
 {
   UpdateRetry ();
   m_tx_err++;
 }
 void 
-OnoeWifiRemoteStation::ReportFinalDataFailed (void)
+OnoeWifiRemoteStation::DoReportFinalDataFailed (void)
 {
   UpdateRetry ();
   m_tx_err++;
--- a/src/devices/wifi/onoe-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/onoe-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -57,13 +57,14 @@
 
   virtual ~OnoeWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/rraa-wifi-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/rraa-wifi-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -81,11 +81,11 @@
 
 
 void 
-RraaWifiRemoteStation::ReportRtsFailed (void)
+RraaWifiRemoteStation::DoReportRtsFailed (void)
 {}
 
 void 
-RraaWifiRemoteStation::ReportDataFailed (void)
+RraaWifiRemoteStation::DoReportDataFailed (void)
 {
   m_lastFrameFail = true;
   CheckTimeout ();
@@ -94,15 +94,15 @@
   RunBasicAlgorithm ();
 }
 void 
-RraaWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+RraaWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {}
 void 
-RraaWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+RraaWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {
   NS_LOG_DEBUG ("self="<<this<<" rts ok");
 }
 void 
-RraaWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+RraaWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   m_lastFrameFail = false;
   CheckTimeout ();
@@ -110,10 +110,10 @@
   RunBasicAlgorithm ();
 }
 void 
-RraaWifiRemoteStation::ReportFinalRtsFailed (void)
+RraaWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-RraaWifiRemoteStation::ReportFinalDataFailed (void)
+RraaWifiRemoteStation::DoReportFinalDataFailed (void)
 {}
 
 WifiMode
--- a/src/devices/wifi/rraa-wifi-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/rraa-wifi-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -87,14 +87,15 @@
   RraaWifiRemoteStation (Ptr<RraaWifiManager> stations);
   virtual ~RraaWifiRemoteStation ();
 
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
   virtual bool NeedRts (Ptr<const Packet> packet);
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
--- a/src/devices/wifi/wifi-phy.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/wifi-phy.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -762,7 +762,7 @@
 {
   NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
   NS_ASSERT (m_nTxPower > 0);
-  double dbm = m_txPowerBaseDbm + (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
+  double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
   return dbm;
 }
 
--- a/src/devices/wifi/wifi-remote-station-manager.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/wifi-remote-station-manager.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -25,6 +25,7 @@
 #include "ns3/boolean.h"
 #include "ns3/uinteger.h"
 #include "ns3/wifi-phy.h"
+#include "ns3/trace-source-accessor.h"
 
 NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager");
 
@@ -41,14 +42,14 @@
 {
 public:
   NonUnicastWifiRemoteStation (Ptr<WifiRemoteStationManager> stations);
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode);
-  virtual void ReportRtsFailed (void);
-  virtual void ReportDataFailed (void);
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
-  virtual void ReportFinalRtsFailed (void);
-  virtual void ReportFinalDataFailed (void);
-
+protected:
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
+  virtual void DoReportRtsFailed (void);
+  virtual void DoReportDataFailed (void);
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  virtual void DoReportFinalRtsFailed (void);
+  virtual void DoReportFinalDataFailed (void);
 private:
   virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
   virtual WifiMode DoGetDataMode (uint32_t size);
@@ -62,35 +63,35 @@
   RecordDisassociated ();
 }
 void 
-NonUnicastWifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+NonUnicastWifiRemoteStation::DoReportRxOk (double rxSnr, WifiMode txMode)
 {
   NS_ASSERT (false);
 }
 void 
-NonUnicastWifiRemoteStation::ReportRtsFailed (void)
+NonUnicastWifiRemoteStation::DoReportRtsFailed (void)
 {
   NS_ASSERT (false);
 }
 void 
-NonUnicastWifiRemoteStation::ReportDataFailed (void)
+NonUnicastWifiRemoteStation::DoReportDataFailed (void)
 {
   NS_ASSERT (false);
 }
 void 
-NonUnicastWifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+NonUnicastWifiRemoteStation::DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
 {
   NS_ASSERT (false);
 }
 void 
-NonUnicastWifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+NonUnicastWifiRemoteStation::DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
 {
   NS_ASSERT (false);
 }
 void 
-NonUnicastWifiRemoteStation::ReportFinalRtsFailed (void)
+NonUnicastWifiRemoteStation::DoReportFinalRtsFailed (void)
 {}
 void 
-NonUnicastWifiRemoteStation::ReportFinalDataFailed (void)
+NonUnicastWifiRemoteStation::DoReportFinalDataFailed (void)
 {}
 
 WifiMode 
@@ -374,8 +375,23 @@
 
 namespace ns3 {
 
+TypeId 
+WifiRemoteStation::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::WifiRemoteStation")
+    .SetParent<Object> ()
+    .AddTraceSource ("Ssrc", "XXX",
+                     MakeTraceSourceAccessor (&WifiRemoteStation::m_ssrc))
+    .AddTraceSource ("Slrc", "XXX",
+                     MakeTraceSourceAccessor (&WifiRemoteStation::m_slrc))
+    ;
+  return tid;
+}
+
 WifiRemoteStation::WifiRemoteStation ()
-  : m_state (BRAND_NEW)
+  : m_state (BRAND_NEW),
+    m_ssrc (0),
+    m_slrc (0)
 {}
 WifiRemoteStation::~WifiRemoteStation ()
 {}
@@ -560,16 +576,16 @@
       return false;
     }
 }
-uint32_t 
-WifiRemoteStation::GetMaxSsrc (Ptr<const Packet> packet)
+bool
+WifiRemoteStation::NeedRtsRetransmission (Ptr<const Packet> packet)
 {
-  return GetManager ()->GetMaxSsrc ();
+  return (m_ssrc < GetManager ()->GetMaxSsrc ());
 }
 
-uint32_t 
-WifiRemoteStation::GetMaxSlrc (Ptr<const Packet> packet)
+bool
+WifiRemoteStation::NeedDataRetransmission (Ptr<const Packet> packet)
 {
-  return GetManager ()->GetMaxSlrc ();
+  return (m_slrc < GetManager ()->GetMaxSlrc ());
 }
 
 bool
@@ -623,5 +639,52 @@
     }
 }
 
+void 
+WifiRemoteStation::ReportRtsFailed (void)
+{
+  m_ssrc++;
+  DoReportRtsFailed ();
+}
+
+void 
+WifiRemoteStation::ReportDataFailed (void)
+{
+  m_slrc++;
+  DoReportDataFailed ();
+}
+
+void 
+WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr)
+{
+  m_ssrc = 0;
+  DoReportRtsOk (ctsSnr, ctsMode, rtsSnr);
+}
+
+void 
+WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr)
+{
+  m_slrc = 0;
+  DoReportDataOk (ackSnr, ackMode, dataSnr);
+}
+
+void 
+WifiRemoteStation::ReportFinalRtsFailed (void)
+{
+  m_ssrc = 0;
+  DoReportFinalRtsFailed ();
+}
+
+void 
+WifiRemoteStation::ReportFinalDataFailed (void)
+{
+  m_slrc = 0;
+  DoReportFinalDataFailed ();
+}
+
+void 
+WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode)
+{
+  DoReportRxOk (rxSnr, txMode);
+}
 } // namespace ns3
 
--- a/src/devices/wifi/wifi-remote-station-manager.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/devices/wifi/wifi-remote-station-manager.h	Mon Mar 31 13:54:41 2008 -0700
@@ -25,6 +25,7 @@
 #include "ns3/mac48-address.h"
 #include "ns3/packet.h"
 #include "ns3/object.h"
+#include "ns3/traced-value.h"
 #include "wifi-mode.h"
 
 namespace ns3 {
@@ -85,6 +86,7 @@
   WifiRemoteStation *Lookup (Mac48Address address);
   WifiRemoteStation *LookupNonUnicast (void);
 protected:
+  friend class WifiRemoteStation;
   virtual void DoDispose (void);
 private:
   typedef std::vector <std::pair<Mac48Address, WifiRemoteStation *> > Stations;
@@ -106,6 +108,9 @@
 
 class WifiRemoteStation {
 public:
+  
+  static TypeId GetTypeId (void);
+  
   WifiRemoteStation ();
   virtual ~WifiRemoteStation ();
 
@@ -130,20 +135,21 @@
   void PrepareForQueue (Ptr<const Packet> packet, uint32_t fullPacketSize);
   WifiMode GetDataMode (Ptr<const Packet> packet, uint32_t fullPacketSize);
   WifiMode GetRtsMode (Ptr<const Packet> packet);
+  // transmission-related methods
+  void ReportRtsFailed (void);
+  void ReportDataFailed (void);
+  void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
+  void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
+  void ReportFinalRtsFailed (void);
+  void ReportFinalDataFailed (void);
 
   // reception-related method
-  virtual void ReportRxOk (double rxSnr, WifiMode txMode) = 0;
+  void ReportRxOk (double rxSnr, WifiMode txMode);
 
-  // transmission-related methods
-  virtual void ReportRtsFailed (void) = 0;
-  virtual void ReportDataFailed (void) = 0;
-  virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0;
-  virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) = 0;
-  virtual void ReportFinalRtsFailed (void) = 0;
-  virtual void ReportFinalDataFailed (void) = 0;
   virtual bool NeedRts (Ptr<const Packet> packet);
-  virtual uint32_t GetMaxSsrc (Ptr<const Packet> packet);
-  virtual uint32_t GetMaxSlrc (Ptr<const Packet> packet);
+  virtual bool NeedRtsRetransmission (Ptr<const Packet> packet);
+  virtual bool NeedDataRetransmission (Ptr<const Packet> packet);
+
   virtual bool NeedFragmentation (Ptr<const Packet> packet);
   virtual uint32_t GetNFragments (Ptr<const Packet> packet);
   virtual uint32_t GetFragmentSize (Ptr<const Packet> packet, uint32_t fragmentNumber);
@@ -158,6 +164,13 @@
   virtual WifiMode DoGetDataMode (uint32_t size) = 0;
   virtual WifiMode DoGetRtsMode (void) = 0;
 protected:
+  virtual void DoReportRtsFailed (void) = 0;
+  virtual void DoReportDataFailed (void) = 0;
+  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0;
+  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) = 0;
+  virtual void DoReportFinalRtsFailed (void) = 0;
+  virtual void DoReportFinalDataFailed (void) = 0;
+  virtual void DoReportRxOk (double rxSnr, WifiMode txMode) = 0;
   uint32_t GetNSupportedModes (void) const;
   WifiMode GetSupportedMode (uint32_t i) const;
 private:
@@ -170,6 +183,8 @@
     GOT_ASSOC_TX_OK
   } m_state;
   SupportedModes m_modes;
+  TracedValue<uint32_t> m_ssrc;
+  TracedValue<uint32_t> m_slrc;
 };
 
 } // namespace ns3 
--- a/src/helper/csma-helper.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/helper/csma-helper.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -3,11 +3,16 @@
 #include "ns3/queue.h"
 #include "ns3/csma-net-device.h"
 #include "ns3/csma-channel.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/config.h"
+#include "ns3/packet.h"
 #include <string>
 
 namespace ns3 {
 
 CsmaHelper::CsmaHelper ()
+  : m_pcap (false), 
+    m_ascii (false)
 {
   m_queueFactory.SetTypeId ("ns3::DropTailQueue");
   m_deviceFactory.SetTypeId ("ns3::CsmaNetDevice");
@@ -40,6 +45,31 @@
   m_channelFactory.Set (n1, v1);
 }
 
+void 
+CsmaHelper::EnablePcap (std::string filename)
+{
+  m_pcap = true;
+  m_pcapFilename = filename;
+}
+void 
+CsmaHelper::DisablePcap (void)
+{
+  m_pcap = false;
+}
+
+void 
+CsmaHelper::EnableAscii (std::ostream &os)
+{
+  m_ascii = true;
+  m_asciiOs = &os;
+}
+void 
+CsmaHelper::DisableAscii (void)
+{
+  m_ascii = false;
+}
+
+
 NetDeviceContainer 
 CsmaHelper::Build (const NodeContainer &c)
 {
@@ -60,10 +90,51 @@
       Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
       device->AddQueue (queue);
       device->Attach (channel);
+      if (m_pcap)
+	{
+	  std::ostringstream oss;
+	  oss << m_pcapFilename << "-" << node->GetId () << "-" << device->GetIfIndex ();
+	  std::string filename = oss.str ();
+	  Ptr<PcapWriter> pcap = Create<PcapWriter> ();
+	  pcap->Open (filename);
+	  pcap->WriteEthernetHeader ();
+	  device->TraceConnectWithoutContext ("Rx", MakeBoundCallback (&CsmaHelper::RxEvent, pcap));
+	  queue->TraceConnectWithoutContext ("Enqueue", MakeBoundCallback (&CsmaHelper::EnqueueEvent, pcap));
+	}
+      if (m_ascii)
+	{
+	  Packet::EnableMetadata ();
+	  std::ostringstream oss;
+	  oss << "/NodeList/" << node->GetId () << "/DeviceList/" << device->GetIfIndex () << "/Rx";
+	  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiEvent, m_asciiOs));
+	  oss.str ("");
+	  oss << "/NodeList/" << node->GetId () << "/DeviceList/" << device->GetIfIndex () << "/TxQueue/Enqueue";
+	  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiEvent, m_asciiOs));
+	  oss.str ("");
+	  oss << "/NodeList/" << node->GetId () << "/DeviceList/" << device->GetIfIndex () << "/TxQueue/Dequeue";
+	  Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiEvent, m_asciiOs));
+	  
+	}
       container.Add (device);
     }
   return container;
 }
 
+void 
+CsmaHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+{
+  writer->WritePacket (packet);
+}
+void 
+CsmaHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+{
+  writer->WritePacket (packet);
+}
+void 
+CsmaHelper::AsciiEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
+{
+  *os << path << " " << *packet << std::endl;
+}
+
 
 } // namespace ns3
--- a/src/helper/csma-helper.h	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/helper/csma-helper.h	Mon Mar 31 13:54:41 2008 -0700
@@ -2,6 +2,7 @@
 #define CSMA_HELPER_H
 
 #include <string>
+#include <ostream>
 #include "ns3/attribute.h"
 #include "ns3/object-factory.h"
 #include "ns3/net-device-container.h"
@@ -10,6 +11,9 @@
 
 namespace ns3 {
 
+class Packet;
+class PcapWriter;
+
 /**
  * \brief build a set of CsmaNetDevice objects
  */
@@ -57,6 +61,24 @@
   void SetChannelParameter (std::string n1, Attribute v1);
 
   /**
+   * \param filename file template to dump pcap traces in.
+   *
+   * Every ns3::CsmaNetDevice created through subsequent calls
+   * to CsmaHelper::Build will be configured to dump
+   * pcap output in a file named filename-nodeid-deviceid.
+   */
+  void EnablePcap (std::string filename);
+  /**
+   * Every ns3::CsmaNetDevice created through subsequent calls
+   * to CsmaHelper::Build will be configured to not dump any pcap
+   * output.
+   */
+  void DisablePcap (void);
+
+  void EnableAscii (std::ostream &os);
+  void DisableAscii (void);
+
+  /**
    * \param c a set of nodes
    *
    * This method creates a simple ns3::CsmaChannel with the
@@ -76,9 +98,16 @@
   NetDeviceContainer Build (const NodeContainer &c, Ptr<CsmaChannel> channel);
 
 private:
+  static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void AsciiEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   ObjectFactory m_queueFactory;
   ObjectFactory m_deviceFactory;
   ObjectFactory m_channelFactory;
+  bool m_pcap;
+  std::string m_pcapFilename;
+  bool m_ascii;
+  std::ostream *m_asciiOs;
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-echo-helper.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -0,0 +1,64 @@
+#include "udp-echo-helper.h"
+#include "ns3/udp-echo-server.h"
+#include "ns3/udp-echo-client.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+UdpEchoServerHelper::UdpEchoServerHelper ()
+  : m_port (9)
+{}
+
+void 
+UdpEchoServerHelper::SetPort (uint16_t port)
+{
+  m_port = port;
+}
+ApplicationContainer 
+UdpEchoServerHelper::Build (NodeContainer c)
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> ("Port", Uinteger (m_port));
+      node->AddApplication (server);
+      apps.Add (server);
+    }
+  return apps;
+}
+
+UdpEchoClientHelper::UdpEchoClientHelper ()
+{
+  m_factory.SetTypeId (UdpEchoClient::GetTypeId ());
+}
+void 
+UdpEchoClientHelper::SetRemote (Ipv4Address ip, uint16_t port)
+{
+  m_remoteIp = ip;
+  m_remotePort = port;
+}
+void 
+UdpEchoClientHelper::SetAppAttribute (std::string name, Attribute value)
+{
+  m_factory.Set (name, value);
+}
+
+ApplicationContainer 
+UdpEchoClientHelper::Build (NodeContainer c)
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<UdpEchoClient> client = m_factory.Create<UdpEchoClient> ();
+      client->SetRemote (m_remoteIp, m_remotePort);
+      node->AddApplication (client);
+      apps.Add (client);
+    }
+  return apps;  
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-echo-helper.h	Mon Mar 31 13:54:41 2008 -0700
@@ -0,0 +1,39 @@
+#ifndef UDP_ECHO_HELPER_H
+#define UDP_ECHO_HELPER_H
+
+#include <stdint.h>
+#include "application-container.h"
+#include "node-container.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class UdpEchoServerHelper
+{
+public:
+  UdpEchoServerHelper ();
+  void SetPort (uint16_t port);
+  ApplicationContainer Build (NodeContainer c);
+private:
+  uint16_t m_port;
+};
+
+class UdpEchoClientHelper
+{
+public:
+  UdpEchoClientHelper ();
+
+  void SetRemote (Ipv4Address ip, uint16_t port);
+  void SetAppAttribute (std::string name, Attribute value);
+  ApplicationContainer Build (NodeContainer c);
+ private:
+  ObjectFactory m_factory;
+  Ipv4Address m_remoteIp;
+  uint16_t m_remotePort;
+};
+
+
+} // namespace ns3
+
+#endif /* UDP_ECHO_HELPER_H */
--- a/src/helper/wscript	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/helper/wscript	Mon Mar 31 13:54:41 2008 -0700
@@ -18,6 +18,7 @@
         'packet-sink-helper.cc',
         'packet-socket-helper.cc',
         'ipv4-interface-container.cc',
+        'udp-echo-helper.cc',
         ]
 
     headers = bld.create_obj('ns3header')
@@ -38,4 +39,5 @@
         'packet-sink-helper.h',
         'packet-socket-helper.h',
         'ipv4-interface-container.h',
+        'udp-echo-helper.h',
         ]
--- a/src/internet-node/tcp-header.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/internet-node/tcp-header.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -150,11 +150,41 @@
 }
 void TcpHeader::Print (std::ostream &os)  const
 {
-  //XXX
+  os << m_sourcePort << " > " << m_destinationPort;
+  if(m_flags!=0)
+  {
+    os<<" [";
+    if((m_flags & FIN) != 0)
+    {
+      os<<" FIN ";
+    }
+    if((m_flags & SYN) != 0)
+    {
+      os<<" SYN ";
+    }
+    if((m_flags & RST) != 0)
+    {
+      os<<" RST ";
+    }
+    if((m_flags & PSH) != 0)
+    {
+      os<<" PSH ";
+    }
+    if((m_flags & ACK) != 0)
+    {
+      os<<" ACK ";
+    }
+    if((m_flags & URG) != 0)
+    {
+      os<<" URG ";
+    }
+    os<<"]";
+  }
+  os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
 }
 uint32_t TcpHeader::GetSerializedSize (void)  const
 {
-  return 20;  //tcp headers are 20 bytes
+  return 4*m_length;
 }
 void TcpHeader::Serialize (Buffer::Iterator start)  const
 {
--- a/src/node/packet-socket.cc	Wed Mar 26 21:28:27 2008 -0700
+++ b/src/node/packet-socket.cc	Mon Mar 31 13:54:41 2008 -0700
@@ -116,7 +116,7 @@
     }
   else
     {
-      m_node->GetDevice (address.GetSingleDevice ());
+      dev = m_node->GetDevice (address.GetSingleDevice ());
     }
   m_node->RegisterProtocolHandler (MakeCallback (&PacketSocket::ForwardUp, this),
                                    address.GetProtocol (), dev);