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