Statistics - almost done
authorKirill Andreev <andreev@iitp.ru>
Wed, 20 May 2009 18:30:27 +0400
changeset 5012 c81291702113
parent 5011 79b4af29924a
child 5013 290579bb1c1b
Statistics - almost done
src/devices/mesh/dot11s/dot11s-helper.cc
src/devices/mesh/dot11s/dot11s-helper.h
src/devices/mesh/dot11s/hwmp-mac-plugin.cc
src/devices/mesh/dot11s/hwmp-mac-plugin.h
src/devices/mesh/dot11s/hwmp-protocol.cc
src/devices/mesh/dot11s/hwmp-protocol.h
src/devices/mesh/dot11s/peer-management-plugin.cc
src/devices/mesh/dot11s/peer-management-plugin.h
src/devices/mesh/dot11s/peer-management-protocol.cc
src/devices/mesh/dot11s/peer-management-protocol.h
src/devices/mesh/mesh-wifi-interface-mac-plugin.h
--- a/src/devices/mesh/dot11s/dot11s-helper.cc	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/dot11s-helper.cc	Wed May 20 18:30:27 2009 +0400
@@ -21,7 +21,7 @@
 
 
 #include "dot11s-helper.h"
-
+#include "ns3/simulator.h"
 #include "ns3/mesh-point-device.h"
 #include "ns3/wifi-net-device.h"
 #include "ns3/wifi-phy.h"
@@ -157,10 +157,35 @@
   return Install (phy, NodeContainer (node), roots, nInterfaces);
 }
 void
-MeshWifiHelper::Report (const ns3::Ptr<ns3::NetDevice>&, std::ofstream&)
+MeshWifiHelper::Report (const ns3::Ptr<ns3::NetDevice>& device, std::ostream& os)
 {
   NS_LOG_UNCOND("Report must be here:");
+  Ptr <MeshPointDevice> mp = device->GetObject<MeshPointDevice> ();
+  NS_ASSERT (mp != 0);
+  std::vector<Ptr<NetDevice> > ifaces = mp->GetInterfaces ();
+  os << "<MeshPointDevice ReportTime=\"" << Simulator::Now().GetSeconds() << "s\">\n";
+  for (std::vector<Ptr<NetDevice> >::const_iterator i = ifaces.begin(); i != ifaces.end(); ++i)
+  {
+    Ptr<WifiNetDevice> device = (*i)->GetObject<WifiNetDevice> ();
+    NS_ASSERT (device != 0);
+    Ptr<MeshWifiInterfaceMac> mac = device->GetMac()->GetObject<MeshWifiInterfaceMac> ();
+    NS_ASSERT (mac != 0);
+    os << "<Interface "
+      "Index=\"" << device->GetIfIndex () << "\" "
+      "BeaconInterval=\"" << mac->GetBeaconInterval ().GetSeconds() << "s\" "
+      "Channel=\"" << mac->GetFrequencyChannel () << "\" "
+      "/>\n";
+  }
+  os << "</MeshPointDevice>\n";
+  Ptr <HwmpProtocol> hwmp = mp->GetObject<HwmpProtocol> ();
+  NS_ASSERT(hwmp != 0);
+  hwmp->Report (os);
+
+  Ptr <PeerManagementProtocol> pmp = mp->GetObject<PeerManagementProtocol> ();
+  NS_ASSERT(pmp != 0);
+  pmp->Report (os);
 }
+
 } // namespace dot11s
 } //namespace ns3
 
--- a/src/devices/mesh/dot11s/dot11s-helper.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/dot11s-helper.h	Wed May 20 18:30:27 2009 +0400
@@ -79,7 +79,7 @@
    * \return list of created mesh point devices, see MeshPointDevice
    */ 
   NetDeviceContainer Install (const WifiPhyHelper &phy, Ptr<Node> node,  std::vector<uint32_t> roots = std::vector<uint32_t> (), uint32_t nInterfaces = 1) const;
-  static void Report (const ns3::Ptr<ns3::NetDevice>&, std::ofstream&);
+  static void Report (const ns3::Ptr<ns3::NetDevice>&, std::ostream&);
 private:
   Ssid m_ssid;
   Time m_randomStartDelay;
--- a/src/devices/mesh/dot11s/hwmp-mac-plugin.cc	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-mac-plugin.cc	Wed May 20 18:30:27 2009 +0400
@@ -60,6 +60,8 @@
       NS_ASSERT (false);
     }
     packet->RemoveHeader(meshHdr);
+    m_stats.recvData ++;
+    m_stats.recvDataBytes += packet->GetSize ();
     //TODO: address extension
     Mac48Address destination;
     switch (meshHdr.GetAddressExt ())
@@ -85,6 +87,8 @@
   }
   if(header.IsAction())
   {
+    m_stats.recvMgt ++;
+    m_stats.recvMgtBytes += packet->GetSize ();
     WifiMeshActionHeader actionHdr;
     packet->RemoveHeader (actionHdr);
     WifiMeshActionHeader::ActionValue actionValue = actionHdr.GetAction ();
@@ -95,6 +99,7 @@
       case WifiMeshActionHeader::PATH_REQUEST:
         {
           IePreq preq;
+          m_stats.recvPreq ++;
           packet->RemoveHeader (preq);
           if(preq.GetOriginatorAddress () == m_protocol->GetAddress ())
             return false;
@@ -107,6 +112,7 @@
       case WifiMeshActionHeader::PATH_REPLY:
         {
           IePrep prep;
+          m_stats.recvPrep ++;
           packet->RemoveHeader (prep);
           if(prep.GetTtl () == 0)
             return false;
@@ -117,6 +123,7 @@
       case WifiMeshActionHeader::PATH_ERROR:
         {
           IePerr perr;
+          m_stats.recvPerr ++;
           packet->RemoveHeader (perr);
           m_protocol->ReceivePerr (perr, header.GetAddr2 (), m_ifIndex, header.GetAddr3 ());
           return false;
@@ -128,9 +135,8 @@
   return true;
 }
 bool
-HwmpMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const
+HwmpMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to)
 {
-  //TODO: add a mesh header and remove a TAG
   if(!header.IsData ())
     return true;
   HwmpTag tag;
@@ -140,7 +146,8 @@
      //do it this way to silence compiler
      NS_ASSERT (false);
   }
-  
+  m_stats.sentData ++;
+  m_stats.sentDataBytes += packet->GetSize ();
   MeshHeader meshHdr;
   meshHdr.SetMeshSeqno(tag.GetSeqno());
   meshHdr.SetMeshTtl(tag.GetTtl());
@@ -206,6 +213,9 @@
   for(std::vector<Mac48Address>::const_iterator i = receivers.begin (); i != receivers.end (); i ++)
   {
     hdr.SetAddr1 (*i);
+    m_stats.sentPreq ++;
+    m_stats.sentMgt ++;
+    m_stats.sentMgtBytes += packet->GetSize ();
     m_parent->SendManagementFrame(packet, hdr);
   }
   //erase queue
@@ -242,6 +252,9 @@
   for(std::vector<Mac48Address>::const_iterator i = m_myPerr.receivers.begin (); i != m_myPerr.receivers.end (); i ++)
   {
     hdr.SetAddr1 (*i);
+    m_stats.sentPerr ++;
+    m_stats.sentMgt ++;
+    m_stats.sentMgtBytes += packet->GetSize ();
     m_parent->SendManagementFrame(packet, hdr);
   }
   m_myPerr.perr.ResetPerr ();
@@ -268,6 +281,9 @@
   hdr.SetAddr2 (m_parent->GetAddress ());
   hdr.SetAddr3 (m_protocol->GetAddress ());
   //Send Management frame
+  m_stats.sentPrep ++;
+  m_stats.sentMgt ++;
+  m_stats.sentMgtBytes += packet->GetSize ();
   m_parent->SendManagementFrame(packet, hdr);
 }
 void
@@ -295,5 +311,30 @@
 {
   return m_parent->GetFrequencyChannel ();
 }
+void
+HwmpMacPlugin::Statistics::Print (std::ostream & os) const
+{
+  os <<"sentPreq= \"" << sentPreq << "\""
+    "sentPrep=\"" << sentPrep << "\""
+    "sentPerr=\"" << sentPerr << "\""
+    "recvPreq=\"" << recvPreq << "\""
+    "recvPrep=\"" << recvPrep << "\""
+    "recvPerr=\"" << recvPerr << "\""
+    "sentMgt=\"" << sentMgt << "\""
+    "sentMgtBytes=\"" << sentMgtBytes  / 1024 << "K\""
+    "recvMgt=\"" << recvMgt << "\""
+    "recvMgtBytes=\"" << recvMgtBytes / 1204 << "K\""
+    "sentData=\"" << sentData << "\""
+    "sentDataBytes=\"" << sentDataBytes / 1024 << "K\""
+    "recvData=\"" << recvData << "\""
+    "recvDataBytes=\"" << recvDataBytes / 1024 << "K\"\n";
+}
+void
+HwmpMacPlugin::Report (std::ostream & os) const
+{
+  os << "<HwmpMacPlugin index=\""<< m_ifIndex <<"\">\n";
+  m_stats.Print(os);
+  os << "</HwmpMacPlugin>\n";
+}
 } //namespace dot11s
 }//namespace ns3
--- a/src/devices/mesh/dot11s/hwmp-mac-plugin.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-mac-plugin.h	Wed May 20 18:30:27 2009 +0400
@@ -50,7 +50,7 @@
   //\{
   void SetParent (Ptr<MeshWifiInterfaceMac> parent);
   bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
-  bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const;
+  bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to);
   /// Update beacon is empty, because HWMP does not know anything about beacons
   void UpdateBeacon (MeshWifiBeacon & beacon) const {};
   //\}
@@ -79,6 +79,8 @@
   //peer as routing entry
   uint32_t GetLinkMetric (Mac48Address peerAddress) const;
   uint16_t GetChannelId () const;
+  ///\brief Statistics:
+  void Report (std::ostream &) const;
 private:
   Ptr<MeshWifiInterfaceMac> m_parent;
   uint32_t m_ifIndex;
@@ -99,37 +101,41 @@
   MyPerr m_myPerr;
   ///\name Statistics:
   ///\{
-    struct Statistics
-    {
-      uint16_t sentPreq;
-      uint16_t recvPreq;
-      uint16_t sentPrep;
-      uint16_t recvPrep;
-      uint16_t sentPerr;
-      uint16_t recvPerr;
-      uint16_t sentMgt;
-      uint32_t sentMgtBytes;
-      uint16_t recvMgt;
-      uint32_t recvMgtBytes;
-      uint16_t sentData;
-      uint32_t sentDataBytes;
-      
-      void Print (std::ostream & os) const;
-      Statistics () : 
-        sentPreq (0), 
-        recvPreq (0),
-        sentPrep (0),
-        recvPrep (0),
-        sentPerr (0),
-        recvPerr (0),
-        sentMgt (0),
-        sentMgtBytes (0),
-        recvMgt (0),
-        recvMgtBytes (0),
-        sentData (0),
-        sentDataBytes (0)
+  struct Statistics
+  {
+    uint16_t sentPreq;
+    uint16_t recvPreq;
+    uint16_t sentPrep;
+    uint16_t recvPrep;
+    uint16_t sentPerr;
+    uint16_t recvPerr;
+    uint16_t sentMgt;
+    uint32_t sentMgtBytes;
+    uint16_t recvMgt;
+    uint32_t recvMgtBytes;
+    uint16_t sentData;
+    uint32_t sentDataBytes;
+    uint16_t recvData;
+    uint32_t recvDataBytes;
+    void Print (std::ostream & os) const;
+    Statistics () : 
+      sentPreq (0), 
+      recvPreq (0),
+      sentPrep (0),
+      recvPrep (0),
+      sentPerr (0),
+      recvPerr (0),
+      sentMgt (0),
+      sentMgtBytes (0),
+      recvMgt (0),
+      recvMgtBytes (0),
+      sentData (0),
+      sentDataBytes (0),
+      recvData (0),
+      recvDataBytes (0)
       {}
-    };
+  };
+  Statistics m_stats;
   ///\}
 };
 } //namespace dot11s
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc	Wed May 20 18:30:27 2009 +0400
@@ -225,6 +225,8 @@
   }
   if (destination == Mac48Address::GetBroadcast ())
   {
+    m_stats.forwardedBroadcast ++;
+    m_stats.forwardedBytes += packet->GetSize ();
     //channel IDs where we have already sent broadcast:
     std::vector<uint16_t> channels;
     for(HwmpPluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++)
@@ -595,11 +597,11 @@
   for (std::vector<Ptr<NetDevice> >::const_iterator i = interfaces.begin (); i != interfaces.end(); i++)
     {
       // Checking for compatible net device
-      const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
-      if (wifiNetDev == NULL)
+      Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
+      if (wifiNetDev == 0)
         return false;
-      MeshWifiInterfaceMac * mac = dynamic_cast<MeshWifiInterfaceMac *> (PeekPointer (wifiNetDev->GetMac ()));
-      if (mac == NULL)
+      Ptr<MeshWifiInterfaceMac>  mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
+      if (mac == 0)
         return false;
       // Installing plugins:
       Ptr<HwmpMacPlugin> hwmpMac = Create<HwmpMacPlugin> (wifiNetDev->GetIfIndex (), this);
@@ -761,6 +763,8 @@
     packet.pkt->RemovePacketTag(tag);
     tag.SetAddress (result.retransmitter);
     packet.pkt->AddPacketTag (tag);
+    m_stats.forwardedUnicast ++;
+    m_stats.forwardedBytes += packet.pkt->GetSize ();
     packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
   }
 }
@@ -781,9 +785,10 @@
     NS_ASSERT (packet.pkt->PeekPacketTag(tag));
     tag.SetAddress (result.retransmitter);
     packet.pkt->AddPacketTag (tag);
+    m_stats.forwardedUnicast ++;
+    m_stats.forwardedBytes += packet.pkt->GetSize ();
     packet.reply (true, packet.pkt, packet.src, packet.dst, packet.protocol, result.ifIndex);
   }
-
 }
 
 bool
@@ -931,20 +936,24 @@
 //Statistics:
 void HwmpProtocol::Statistics::Print (std::ostream & os) const
 {
-  os << "<Statistics: "
-    "forwardedUnicast= \"" << forwardedUnicast << "\""
-    "forwardedBroadcast= \"" << forwardedBroadcast << "\""
-    "totalQueued= \"" << totalQueued << "\""
-    "totalDropped= \"" << totalDropped << "\"";
+  os << "forwardedUnicast=\"" << forwardedUnicast << "\""
+    "forwardedBroadcast=\"" << forwardedBroadcast << "\""
+    "forwardedBytes=\"" << forwardedBytes / 1024 << "K\""
+    "totalQueued=\"" << totalQueued << "\""
+    "totalDropped=\"" << totalDropped << "\"\n";
 }
 void
 HwmpProtocol::Report (std::ostream & os) const
 {
-  os << "<HWMP Protocol"
+  os << "<Hwmp>\n"
     "address=\"" << m_address << "\" "
-    ">\n";
+    "\n";
   m_stats.Print (os);
-  os << "<HWMP>\n";
+  for(HwmpPluginMap::const_iterator plugin = m_interfaces.begin (); plugin != m_interfaces.end (); plugin ++)
+  {
+    plugin->second->Report(os);
+  }
+  os << "</Hwmp>\n";
 }
 } //namespace dot11s
 } //namespace ns3
--- a/src/devices/mesh/dot11s/hwmp-protocol.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/hwmp-protocol.h	Wed May 20 18:30:27 2009 +0400
@@ -148,7 +148,7 @@
     uint16_t totalDropped;
 
     void Print (std::ostream & os) const;
-    Statistics () : forwardedUnicast (0), forwardedBroadcast (0), totalQueued (0), totalDropped (0) {}
+    Statistics () : forwardedUnicast (0), forwardedBroadcast (0), forwardedBytes (0), totalQueued (0), totalDropped (0) {}
   };
   Statistics m_stats;
   ///\}
--- a/src/devices/mesh/dot11s/peer-management-plugin.cc	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/peer-management-plugin.cc	Wed May 20 18:30:27 2009 +0400
@@ -78,18 +78,9 @@
     WifiMeshActionHeader::ActionValue actionValue = actionHdr.GetAction ();
     // If can not handle - just return;
     if(actionHdr.GetCategory () != WifiMeshActionHeader::MESH_PEER_LINK_MGT)
-    {
-      if(m_protocol->IsActiveLink(m_ifIndex,header.GetAddr2()))
-      {
-        m_stats.received ++;
-        return true;
-      }
-      else
-      {
-        m_stats.dropped ++;
-        return false;
-      }
-    }
+      return m_protocol->IsActiveLink(m_ifIndex,header.GetAddr2());
+    m_stats.recvMgt ++;
+    m_stats.recvMgtBytes += packet->GetSize ();
     Mac48Address peerAddress = header.GetAddr2 ();
     Mac48Address peerMpAddress = header.GetAddr3 ();
     PeerLinkFrameStart::PlinkFrameStartFields fields;
@@ -143,19 +134,10 @@
     // if we can handle a frame - drop it
     return false;
   }
-  if(m_protocol->IsActiveLink(m_ifIndex,header.GetAddr2()))
-  {
-    m_stats.received ++;
-    return true;
-  }
-  else
-  {
-    m_stats.dropped ++;
-    return false;
-  }
+  return m_protocol->IsActiveLink(m_ifIndex,header.GetAddr2());
 }
 bool
-PeerManagerMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const
+PeerManagerMacPlugin::UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to)
 {
   if(header.IsAction ())
   {
@@ -168,7 +150,15 @@
   if(header.GetAddr1 ().IsGroup ())
     return true;
   else
-    return m_protocol->IsActiveLink(m_ifIndex,header.GetAddr1());
+  {
+    if(m_protocol->IsActiveLink(m_ifIndex,header.GetAddr1()))
+      return true;
+    else
+    {
+      m_stats.dropped ++;
+      return false;
+    }
+  }
 }
 void
 PeerManagerMacPlugin::UpdateBeacon (MeshWifiBeacon & beacon) const
@@ -226,6 +216,8 @@
   plinkFrame.SetPlinkFrameStart(fields);
   packet->AddHeader (plinkFrame);
   packet->AddHeader (actionHdr);
+  m_stats.sentMgt ++;
+  m_stats.sentMgtBytes += packet->GetSize ();
   // Wifi Mac header:
   WifiMacHeader hdr;
   hdr.SetAction ();
@@ -265,34 +257,37 @@
   recvOpen (0),
   recvConfirm (0),
   recvClose (0),
-  received (0),
   dropped (0),
-  brokenMgt (0)
+  brokenMgt (0),
+  sentMgt (0),
+  sentMgtBytes (0),
+  recvMgt (0),
+  recvMgtBytes (0)
 {
 }
 void
 PeerManagerMacPlugin::Statistics::Print (std::ostream & os) const
 {
-  os << "<Statistics: "
-    "sendOpen= \"" << sendOpen << "\""
-    "sendConfirm=\"" << sendConfirm << "\" "
-    "sendClose=\"" << sendClose << "\" "
-    "recvOpen=\"" << recvOpen << "\" "
-    "recvConfirm=\"" << recvConfirm << "\" "
-    "recvClose=\"" << recvClose << "\" "
-    "received=\"" << received << "\" "
-    "dropped=\"" << dropped << "\" "
-    "brokenMgt=\"" << brokenMgt << "\" "
-    "/>\n";
+  os << "sendOpen=\"" << sendOpen << "\""
+    "sendConfirm=\"" << sendConfirm << "\""
+    "sendClose=\"" << sendClose << "\""
+    "recvOpen=\"" << recvOpen << "\""
+    "recvConfirm=\"" << recvConfirm << "\""
+    "recvClose=\"" << recvClose << "\""
+    "dropped=\"" << dropped << "\""
+    "brokenMgt=\"" << brokenMgt << "\""
+    "sentMgt=\"" << sentMgt << "\""
+    "sentMgtBytes=\"" << sentMgtBytes << "\""
+    "recvMgt=\"" << recvMgt << "\""
+    "recvMgtBytes=\"" << recvMgtBytes << "\"\n";
 }
 void
 PeerManagerMacPlugin::Report (std::ostream & os) const
 {
-  os << "<Peer Management Protocol Mac "
-    "index=\"" << m_ifIndex << "\" "
-    ">\n";
+  os << "<PMP-MAC "
+    "index=\"" << m_ifIndex << "\">\n";
   m_stats.Print (os);
-  os << "<PMP MAC>\n";
+  os << "</PMP MAC>\n";
 }
 } // namespace dot11s
 } //namespace ns3
--- a/src/devices/mesh/dot11s/peer-management-plugin.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/peer-management-plugin.h	Wed May 20 18:30:27 2009 +0400
@@ -48,7 +48,7 @@
   ///\{
   void SetParent (Ptr<MeshWifiInterfaceMac> parent);
   bool Receive (Ptr<Packet> packet, const WifiMacHeader & header);
-  bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const;
+  bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to);
   void UpdateBeacon (MeshWifiBeacon & beacon) const;
   void Report (std::ostream &) const;
   ///\}
@@ -106,7 +106,6 @@
     uint16_t recvOpen;
     uint16_t recvConfirm;
     uint16_t recvClose;
-    uint16_t received;
     uint16_t dropped;
     uint16_t brokenMgt;
     uint16_t sentMgt;
--- a/src/devices/mesh/dot11s/peer-management-protocol.cc	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/peer-management-protocol.cc	Wed May 20 18:30:27 2009 +0400
@@ -96,11 +96,11 @@
   std::vector<Ptr<NetDevice> > interfaces = mp->GetInterfaces ();
   for(std::vector<Ptr<NetDevice> >::iterator i = interfaces.begin(); i != interfaces.end(); i ++)
   {
-    const WifiNetDevice * wifiNetDev = dynamic_cast<const WifiNetDevice *> (PeekPointer (*i));
-      if (wifiNetDev == NULL)
-        return false;
-    MeshWifiInterfaceMac * mac = dynamic_cast<MeshWifiInterfaceMac *> (PeekPointer (wifiNetDev->GetMac ()));
-    if (mac == NULL)
+    Ptr<WifiNetDevice> wifiNetDev = (*i)->GetObject<WifiNetDevice> ();
+    if (wifiNetDev == 0)
+      return false;
+    Ptr<MeshWifiInterfaceMac>  mac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
+    if (mac == 0)
       return false;
     Ptr<PeerManagerMacPlugin> peerPlugin = Create<PeerManagerMacPlugin> ((*i)->GetIfIndex(), this);
     mac->InstallPlugin(peerPlugin);
@@ -466,6 +466,12 @@
 {
   return m_address;
 }
+void
+PeerManagementProtocol::Report (std::ostream & os) const
+{
+  for(PeerManagerPluginMap::const_iterator plugins = m_plugins.begin (); plugins != m_plugins.end (); plugins ++)
+    plugins->second->Report (os);
+}
 } // namespace dot11s
 } //namespace ns3
 
--- a/src/devices/mesh/dot11s/peer-management-protocol.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/dot11s/peer-management-protocol.h	Wed May 20 18:30:27 2009 +0400
@@ -135,6 +135,8 @@
   ///\brief needed by plugins to set global source address
   Mac48Address GetAddress ();
   ///\brief: Report statistics
+  void Report (std::ostream &) const;
+
 private:
   /** \name Private structures
    * \{
--- a/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Wed May 20 14:03:26 2009 +0400
+++ b/src/devices/mesh/mesh-wifi-interface-mac-plugin.h	Wed May 20 18:30:27 2009 +0400
@@ -58,7 +58,7 @@
    * \return false if (and only if) frame should be dropped
    * TODO define when MAC call this, preconditions & postconditions
    */
-  virtual bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) const = 0;
+  virtual bool UpdateOutcomingFrame (Ptr<Packet> packet, WifiMacHeader & header, Mac48Address from, Mac48Address to) = 0;
   /**
    * \brief Update beacon before it will be formed and sent
    *