A Discrete-Event Network Simulator
API
point-to-point-helper.cc
Go to the documentation of this file.
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 
21 #include "ns3/abort.h"
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include "ns3/point-to-point-net-device.h"
25 #include "ns3/point-to-point-channel.h"
26 #include "ns3/queue.h"
27 #include "ns3/net-device-queue-interface.h"
28 #include "ns3/config.h"
29 #include "ns3/packet.h"
30 #include "ns3/names.h"
31 
32 #ifdef NS3_MPI
33 #include "ns3/mpi-interface.h"
34 #include "ns3/mpi-receiver.h"
35 #include "ns3/point-to-point-remote-channel.h"
36 #endif
37 
38 #include "ns3/trace-helper.h"
39 #include "point-to-point-helper.h"
40 
41 namespace ns3 {
42 
43 NS_LOG_COMPONENT_DEFINE ("PointToPointHelper");
44 
46 {
47  m_queueFactory.SetTypeId ("ns3::DropTailQueue<Packet>");
48  m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice");
49  m_channelFactory.SetTypeId ("ns3::PointToPointChannel");
50 }
51 
52 void
53 PointToPointHelper::SetQueue (std::string type,
54  std::string n1, const AttributeValue &v1,
55  std::string n2, const AttributeValue &v2,
56  std::string n3, const AttributeValue &v3,
57  std::string n4, const AttributeValue &v4)
58 {
60 
62  m_queueFactory.Set (n1, v1);
63  m_queueFactory.Set (n2, v2);
64  m_queueFactory.Set (n3, v3);
65  m_queueFactory.Set (n4, v4);
66 }
67 
68 void
70 {
71  m_deviceFactory.Set (n1, v1);
72 }
73 
74 void
76 {
77  m_channelFactory.Set (n1, v1);
78 }
79 
80 void
81 PointToPointHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
82 {
83  //
84  // All of the Pcap enable functions vector through here including the ones
85  // that are wandering through all of devices on perhaps all of the nodes in
86  // the system. We can only deal with devices of type PointToPointNetDevice.
87  //
88  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
89  if (device == 0)
90  {
91  NS_LOG_INFO ("PointToPointHelper::EnablePcapInternal(): Device " << device << " not of type ns3::PointToPointNetDevice");
92  return;
93  }
94 
95  PcapHelper pcapHelper;
96 
97  std::string filename;
98  if (explicitFilename)
99  {
100  filename = prefix;
101  }
102  else
103  {
104  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
105  }
106 
107  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
109  pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", file);
110 }
111 
112 void
114  Ptr<OutputStreamWrapper> stream,
115  std::string prefix,
116  Ptr<NetDevice> nd,
117  bool explicitFilename)
118 {
119  //
120  // All of the ascii enable functions vector through here including the ones
121  // that are wandering through all of devices on perhaps all of the nodes in
122  // the system. We can only deal with devices of type PointToPointNetDevice.
123  //
124  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
125  if (device == 0)
126  {
127  NS_LOG_INFO ("PointToPointHelper::EnableAsciiInternal(): Device " << device <<
128  " not of type ns3::PointToPointNetDevice");
129  return;
130  }
131 
132  //
133  // Our default trace sinks are going to use packet printing, so we have to
134  // make sure that is turned on.
135  //
137 
138  //
139  // If we are not provided an OutputStreamWrapper, we are expected to create
140  // one using the usual trace filename conventions and do a Hook*WithoutContext
141  // since there will be one file per context and therefore the context would
142  // be redundant.
143  //
144  if (stream == 0)
145  {
146  //
147  // Set up an output stream object to deal with private ofstream copy
148  // constructor and lifetime issues. Let the helper decide the actual
149  // name of the file given the prefix.
150  //
151  AsciiTraceHelper asciiTraceHelper;
152 
153  std::string filename;
154  if (explicitFilename)
155  {
156  filename = prefix;
157  }
158  else
159  {
160  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
161  }
162 
163  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
164 
165  //
166  // The MacRx trace source provides our "r" event.
167  //
168  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<PointToPointNetDevice> (device, "MacRx", theStream);
169 
170  //
171  // The "+", '-', and 'd' events are driven by trace sources actually in the
172  // transmit queue.
173  //
174  Ptr<Queue<Packet> > queue = device->GetQueue ();
175  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue<Packet> > (queue, "Enqueue", theStream);
176  asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue<Packet> > (queue, "Drop", theStream);
177  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue<Packet> > (queue, "Dequeue", theStream);
178 
179  // PhyRxDrop trace source for "d" event
180  asciiTraceHelper.HookDefaultDropSinkWithoutContext<PointToPointNetDevice> (device, "PhyRxDrop", theStream);
181 
182  return;
183  }
184 
185  //
186  // If we are provided an OutputStreamWrapper, we are expected to use it, and
187  // to providd a context. We are free to come up with our own context if we
188  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
189  // compatibility and simplicity, we just use Config::Connect and let it deal
190  // with the context.
191  //
192  // Note that we are going to use the default trace sinks provided by the
193  // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
194  // but the default trace sinks are actually publicly available static
195  // functions that are always there waiting for just such a case.
196  //
197  uint32_t nodeid = nd->GetNode ()->GetId ();
198  uint32_t deviceid = nd->GetIfIndex ();
199  std::ostringstream oss;
200 
201  oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
203 
204  oss.str ("");
205  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
207 
208  oss.str ("");
209  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Dequeue";
211 
212  oss.str ("");
213  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Drop";
215 
216  oss.str ("");
217  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/PhyRxDrop";
219 }
220 
223 {
224  NS_ASSERT (c.GetN () == 2);
225  return Install (c.Get (0), c.Get (1));
226 }
227 
230 {
231  NetDeviceContainer container;
232 
234  devA->SetAddress (Mac48Address::Allocate ());
235  a->AddDevice (devA);
237  devA->SetQueue (queueA);
239  devB->SetAddress (Mac48Address::Allocate ());
240  b->AddDevice (devB);
242  devB->SetQueue (queueB);
243  // Aggregate NetDeviceQueueInterface objects
244  Ptr<NetDeviceQueueInterface> ndqiA = CreateObject<NetDeviceQueueInterface> ();
245  ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
246  devA->AggregateObject (ndqiA);
247  Ptr<NetDeviceQueueInterface> ndqiB = CreateObject<NetDeviceQueueInterface> ();
248  ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
249  devB->AggregateObject (ndqiB);
250 
252 
253  // If MPI is enabled, we need to see if both nodes have the same system id
254  // (rank), and the rank is the same as this instance. If both are true,
255  // use a normal p2p channel, otherwise use a remote channel
256 #ifdef NS3_MPI
257  bool useNormalChannel = true;
259  {
260  uint32_t n1SystemId = a->GetSystemId ();
261  uint32_t n2SystemId = b->GetSystemId ();
262  uint32_t currSystemId = MpiInterface::GetSystemId ();
263  if (n1SystemId != currSystemId || n2SystemId != currSystemId)
264  {
265  useNormalChannel = false;
266  }
267  }
268  if (useNormalChannel)
269  {
270  m_channelFactory.SetTypeId ("ns3::PointToPointChannel");
272  }
273  else
274  {
275  m_channelFactory.SetTypeId ("ns3::PointToPointRemoteChannel");
277  Ptr<MpiReceiver> mpiRecA = CreateObject<MpiReceiver> ();
278  Ptr<MpiReceiver> mpiRecB = CreateObject<MpiReceiver> ();
279  mpiRecA->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devA));
280  mpiRecB->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devB));
281  devA->AggregateObject (mpiRecA);
282  devB->AggregateObject (mpiRecB);
283  }
284 #else
286 #endif
287 
288  devA->Attach (channel);
289  devB->Attach (channel);
290  container.Add (devA);
291  container.Add (devB);
292 
293  return container;
294 }
295 
298 {
299  Ptr<Node> b = Names::Find<Node> (bName);
300  return Install (a, b);
301 }
302 
305 {
306  Ptr<Node> a = Names::Find<Node> (aName);
307  return Install (a, b);
308 }
309 
311 PointToPointHelper::Install (std::string aName, std::string bName)
312 {
313  Ptr<Node> a = Names::Find<Node> (aName);
314  Ptr<Node> b = Names::Find<Node> (bName);
315  return Install (a, b);
316 }
317 
318 } // namespace ns3
virtual void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename)
Enable pcap output the indicated net device.
Manage ASCII trace files for device models.
Definition: trace-helper.h:161
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
static void DefaultEnqueueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Enqueue default trace sink.
void HookDefaultDropSinkWithoutContext(Ptr< T > object, std::string traceName, Ptr< OutputStreamWrapper > stream)
Hook a trace source to the default drop operation trace sink that does not accept nor log a trace con...
Definition: trace-helper.h:483
NetDeviceContainer Install(NodeContainer c)
Hold a value for an Attribute.
Definition: attribute.h:68
Manage pcap files for device models.
Definition: trace-helper.h:38
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
void SetQueue(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue())
Each point to point net device must have a queue to pass packets through.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
static void DefaultDropSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Drop default trace sink.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we&#39;ll use to write the traced bits. ...
ObjectFactory m_channelFactory
Channel Factory.
void HookDefaultEnqueueSinkWithoutContext(Ptr< T > object, std::string traceName, Ptr< OutputStreamWrapper > stream)
Hook a trace source to the default enqueue operation trace sink that does not accept nor log a trace ...
Definition: trace-helper.h:461
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the ascii trace helper figure out a reasonable filename to use for an ascii trace file associated...
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, DataLinkType dataLinkType, uint32_t snapLen=std::numeric_limits< uint32_t >::max(), int32_t tzCorrection=0)
Create and initialize a pcap file.
Definition: trace-helper.cc:49
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
static void AppendItemTypeIfNotPresent(std::string &typeId, const std::string &itemType)
Append the item type to the provided type ID if the latter does not end with &#39;>&#39;. ...
Definition: queue.cc:73
channel
Definition: third.py:92
PointToPointHelper()
Create a PointToPointHelper to make life easier when creating point to point networks.
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for a pcap file associated with a device...
Definition: trace-helper.cc:80
A Remote Point-To-Point Channel.
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:572
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
virtual void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename)
Enable ascii trace output on the indicated net device.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static bool IsEnabled()
Returns enabled state of parallel environment.
holds a vector of ns3::NetDevice pointers
A Device for a Point to Point Network Link.
ObjectFactory m_deviceFactory
Device Factory.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
static void DefaultReceiveSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Receive default trace sink.
uint32_t GetN(void) const
Get the number of Ptr<Node> stored in this container.
static void DefaultDequeueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Dequeue default trace sink.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< Queue< Packet > > GetQueue(void) const
Get a copy of the attached Queue.
keep track of a set of node pointers.
uint32_t GetSystemId(void) const
Definition: node.cc:123
void HookDefaultReceiveSinkWithoutContext(Ptr< T > object, std::string traceName, Ptr< OutputStreamWrapper > stream)
Hook a trace source to the default receive operation trace sink that does not accept nor log a trace ...
Definition: trace-helper.h:527
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:130
Simple Point To Point Channel.
static uint32_t GetSystemId()
Get the id number of this rank.
void Receive(Ptr< Packet > p)
Receive a packet from a connected PointToPointChannel.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
ObjectFactory m_queueFactory
Queue Factory.
void HookDefaultSink(Ptr< T > object, std::string traceName, Ptr< PcapFileWrapper > file)
Hook a trace source to the default trace sink.
Definition: trace-helper.h:147
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
void HookDefaultDequeueSinkWithoutContext(Ptr< T > object, std::string traceName, Ptr< OutputStreamWrapper > stream)
Hook a trace source to the default dequeue operation trace sink that does not accept nor log a trace ...
Definition: trace-helper.h:505