src/helper/csma-helper.cc
author Nicola Baldo <nbaldo@cttc.es>
Thu Aug 13 09:36:53 2009 +0200 (2009-08-13)
changeset 4709 b0743dbc4e55
parent 4448 641b88d1e131
child 4712 74ed62336c36
permissions -rw-r--r--
bug 639: add configurable capture size to pcap
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2008 INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    19  */
    20 #include "csma-helper.h"
    21 #include "ns3/simulator.h"
    22 #include "ns3/object-factory.h"
    23 #include "ns3/queue.h"
    24 #include "ns3/csma-net-device.h"
    25 #include "ns3/csma-channel.h"
    26 #include "ns3/pcap-writer.h"
    27 #include "ns3/config.h"
    28 #include "ns3/packet.h"
    29 #include "ns3/names.h"
    30 #include <string>
    31 
    32 namespace ns3 {
    33 
    34 CsmaHelper::CsmaHelper ()
    35 {
    36   m_queueFactory.SetTypeId ("ns3::DropTailQueue");
    37   m_deviceFactory.SetTypeId ("ns3::CsmaNetDevice");
    38   m_channelFactory.SetTypeId ("ns3::CsmaChannel");
    39 }
    40 
    41 void 
    42 CsmaHelper::SetQueue (std::string type,
    43                       std::string n1, const AttributeValue &v1,
    44                       std::string n2, const AttributeValue &v2,
    45                       std::string n3, const AttributeValue &v3,
    46                       std::string n4, const AttributeValue &v4)
    47 {
    48   m_queueFactory.SetTypeId (type);
    49   m_queueFactory.Set (n1, v1);
    50   m_queueFactory.Set (n2, v2);
    51   m_queueFactory.Set (n3, v3);
    52   m_queueFactory.Set (n4, v4);
    53 }
    54 
    55 void 
    56 CsmaHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1)
    57 {
    58   m_deviceFactory.Set (n1, v1);
    59 }
    60 
    61 void 
    62 CsmaHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1)
    63 {
    64   m_channelFactory.Set (n1, v1);
    65 }
    66 
    67 void 
    68 CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
    69 {
    70   std::ostringstream oss;
    71   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/";
    72   Config::MatchContainer matches = Config::LookupMatches (oss.str ());
    73   if (matches.GetN () == 0)
    74     {
    75       return;
    76     }
    77   oss.str ("");
    78   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
    79   Ptr<PcapWriter> pcap = CreateObject<PcapWriter> ();
    80   pcap->Open (oss.str ());
    81   pcap->WriteEthernetHeader ();
    82   oss.str ("");
    83   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
    84   if (promiscuous)
    85     {
    86       oss << "/$ns3::CsmaNetDevice/PromiscSniffer";
    87     }
    88   else
    89     {
    90       oss << "/$ns3::CsmaNetDevice/Sniffer";
    91     }
    92   Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::SniffEvent, pcap));
    93 }
    94 
    95 void 
    96 CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous)
    97 {
    98   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
    99     {
   100       Ptr<NetDevice> dev = *i;
   101       EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex (), promiscuous);
   102     }
   103 }
   104 
   105 void 
   106 CsmaHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous)
   107 {
   108   EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
   109 }
   110 
   111 void 
   112 CsmaHelper::EnablePcap (std::string filename, std::string ndName, bool promiscuous)
   113 {
   114   Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
   115   EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
   116 }
   117 
   118 void
   119 CsmaHelper::EnablePcap (std::string filename, NodeContainer n, bool promiscuous)
   120 {
   121   NetDeviceContainer devs;
   122   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
   123     {
   124       Ptr<Node> node = *i;
   125       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
   126         {
   127           devs.Add (node->GetDevice (j));
   128         }
   129     }
   130   EnablePcap (filename, devs, promiscuous);
   131 }
   132 
   133 void
   134 CsmaHelper::EnablePcapAll (std::string filename, bool promiscuous)
   135 {
   136   EnablePcap (filename, NodeContainer::GetGlobal (), promiscuous);
   137 }
   138 
   139 void 
   140 CsmaHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
   141 {
   142   Packet::EnablePrinting ();
   143   std::ostringstream oss;
   144   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/MacRx";
   145   Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiRxEvent, &os));
   146   oss.str ("");
   147   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
   148   Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiEnqueueEvent, &os));
   149   oss.str ("");
   150   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Dequeue";
   151   Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiDequeueEvent, &os));
   152   oss.str ("");
   153   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Drop";
   154   Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiDropEvent, &os));
   155 }
   156 void 
   157 CsmaHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
   158 {
   159   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
   160     {
   161       Ptr<NetDevice> dev = *i;
   162       EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
   163     }
   164 }
   165 void
   166 CsmaHelper::EnableAscii (std::ostream &os, NodeContainer n)
   167 {
   168   NetDeviceContainer devs;
   169   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
   170     {
   171       Ptr<Node> node = *i;
   172       for (uint32_t j = 0; j < node->GetNDevices (); ++j)
   173         {
   174           devs.Add (node->GetDevice (j));
   175         }
   176     }
   177   EnableAscii (os, devs);
   178 }
   179 
   180 void
   181 CsmaHelper::EnableAsciiAll (std::ostream &os)
   182 {
   183   EnableAscii (os, NodeContainer::GetGlobal ());
   184 }
   185 
   186 NetDeviceContainer
   187 CsmaHelper::Install (Ptr<Node> node) const
   188 {
   189   Ptr<CsmaChannel> channel = m_channelFactory.Create ()->GetObject<CsmaChannel> ();
   190   return Install (node, channel);
   191 }
   192 
   193 NetDeviceContainer
   194 CsmaHelper::Install (std::string nodeName) const
   195 {
   196   Ptr<Node> node = Names::Find<Node> (nodeName);
   197   return Install (node);
   198 }
   199 
   200 NetDeviceContainer
   201 CsmaHelper::Install (Ptr<Node> node, Ptr<CsmaChannel> channel) const
   202 {
   203   return NetDeviceContainer (InstallPriv (node, channel));
   204 }
   205 
   206 NetDeviceContainer
   207 CsmaHelper::Install (Ptr<Node> node, std::string channelName) const
   208 {
   209   Ptr<CsmaChannel> channel = Names::Find<CsmaChannel> (channelName);
   210   return NetDeviceContainer (InstallPriv (node, channel));
   211 }
   212 
   213 NetDeviceContainer
   214 CsmaHelper::Install (std::string nodeName, Ptr<CsmaChannel> channel) const
   215 {
   216   Ptr<Node> node = Names::Find<Node> (nodeName);
   217   return NetDeviceContainer (InstallPriv (node, channel));
   218 }
   219 
   220 NetDeviceContainer
   221 CsmaHelper::Install (std::string nodeName, std::string channelName) const
   222 {
   223   Ptr<Node> node = Names::Find<Node> (nodeName);
   224   Ptr<CsmaChannel> channel = Names::Find<CsmaChannel> (channelName);
   225   return NetDeviceContainer (InstallPriv (node, channel));
   226 }
   227 
   228 NetDeviceContainer 
   229 CsmaHelper::Install (const NodeContainer &c) const
   230 {
   231   Ptr<CsmaChannel> channel = m_channelFactory.Create ()->GetObject<CsmaChannel> ();
   232 
   233   return Install (c, channel);
   234 }
   235 
   236 NetDeviceContainer 
   237 CsmaHelper::Install (const NodeContainer &c, Ptr<CsmaChannel> channel) const
   238 {
   239   NetDeviceContainer devs;
   240 
   241   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
   242     {
   243       devs.Add (InstallPriv (*i, channel));
   244     }
   245 
   246   return devs;
   247 }
   248 
   249 NetDeviceContainer 
   250 CsmaHelper::Install (const NodeContainer &c, std::string channelName) const
   251 {
   252   Ptr<CsmaChannel> channel = Names::Find<CsmaChannel> (channelName);
   253   return Install (c, channel);
   254 }
   255 
   256 Ptr<NetDevice>
   257 CsmaHelper::InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const
   258 {
   259   Ptr<CsmaNetDevice> device = m_deviceFactory.Create<CsmaNetDevice> ();
   260   device->SetAddress (Mac48Address::Allocate ());
   261   node->AddDevice (device);
   262   Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
   263   device->SetQueue (queue);
   264   device->Attach (channel);
   265 
   266   return device;
   267 }
   268 
   269 void 
   270 CsmaHelper::InstallStar (Ptr<Node> hub, NodeContainer spokes, 
   271                          NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices)
   272 {
   273   for (uint32_t i = 0; i < spokes.GetN (); ++i)
   274     {
   275       NodeContainer nodes (hub, spokes.Get (i));
   276       NetDeviceContainer nd = Install (nodes);
   277       hubDevices.Add (nd.Get (0));
   278       spokeDevices.Add (nd.Get (1));
   279     }
   280 }
   281 
   282 void 
   283 CsmaHelper::InstallStar (std::string hubName, NodeContainer spokes, 
   284                          NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices)
   285 {
   286   Ptr<Node> hub = Names::Find<Node> (hubName);
   287   InstallStar (hub, spokes, hubDevices, spokeDevices);
   288 }
   289 
   290 void 
   291 CsmaHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
   292 {
   293   writer->WritePacket (packet);
   294 }
   295 
   296 void 
   297 CsmaHelper::AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
   298 {
   299   *os << "+ " << Simulator::Now ().GetSeconds () << " ";
   300   *os << path << " " << *packet << std::endl;
   301 }
   302 
   303 void 
   304 CsmaHelper::AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
   305 {
   306   *os << "- " << Simulator::Now ().GetSeconds () << " ";
   307   *os << path << " " << *packet << std::endl;
   308 }
   309 
   310 void 
   311 CsmaHelper::AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
   312 {
   313   *os << "d " << Simulator::Now ().GetSeconds () << " ";
   314   *os << path << " " << *packet << std::endl;
   315 }
   316 
   317 void 
   318 CsmaHelper::AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
   319 {
   320   *os << "r " << Simulator::Now ().GetSeconds () << " ";
   321   *os << path << " " << *packet << std::endl;
   322 }
   323 
   324 } // namespace ns3