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 #ifdef NS3_MPI
51  m_remoteChannelFactory.SetTypeId ("ns3::PointToPointRemoteChannel");
52 #endif
53 }
54 
55 void
56 PointToPointHelper::SetQueue (std::string type,
57  std::string n1, const AttributeValue &v1,
58  std::string n2, const AttributeValue &v2,
59  std::string n3, const AttributeValue &v3,
60  std::string n4, const AttributeValue &v4)
61 {
63 
65  m_queueFactory.Set (n1, v1);
66  m_queueFactory.Set (n2, v2);
67  m_queueFactory.Set (n3, v3);
68  m_queueFactory.Set (n4, v4);
69 }
70 
71 void
73 {
74  m_deviceFactory.Set (n1, v1);
75 }
76 
77 void
79 {
80  m_channelFactory.Set (n1, v1);
81 #ifdef NS3_MPI
82  m_remoteChannelFactory.Set (n1, v1);
83 #endif
84 }
85 
86 void
87 PointToPointHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
88 {
89  //
90  // All of the Pcap enable functions vector through here including the ones
91  // that are wandering through all of devices on perhaps all of the nodes in
92  // the system. We can only deal with devices of type PointToPointNetDevice.
93  //
94  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
95  if (device == 0)
96  {
97  NS_LOG_INFO ("PointToPointHelper::EnablePcapInternal(): Device " << device << " not of type ns3::PointToPointNetDevice");
98  return;
99  }
100 
101  PcapHelper pcapHelper;
102 
103  std::string filename;
104  if (explicitFilename)
105  {
106  filename = prefix;
107  }
108  else
109  {
110  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
111  }
112 
113  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
115  pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", file);
116 }
117 
118 void
120  Ptr<OutputStreamWrapper> stream,
121  std::string prefix,
122  Ptr<NetDevice> nd,
123  bool explicitFilename)
124 {
125  //
126  // All of the ascii enable functions vector through here including the ones
127  // that are wandering through all of devices on perhaps all of the nodes in
128  // the system. We can only deal with devices of type PointToPointNetDevice.
129  //
130  Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> ();
131  if (device == 0)
132  {
133  NS_LOG_INFO ("PointToPointHelper::EnableAsciiInternal(): Device " << device <<
134  " not of type ns3::PointToPointNetDevice");
135  return;
136  }
137 
138  //
139  // Our default trace sinks are going to use packet printing, so we have to
140  // make sure that is turned on.
141  //
143 
144  //
145  // If we are not provided an OutputStreamWrapper, we are expected to create
146  // one using the usual trace filename conventions and do a Hook*WithoutContext
147  // since there will be one file per context and therefore the context would
148  // be redundant.
149  //
150  if (stream == 0)
151  {
152  //
153  // Set up an output stream object to deal with private ofstream copy
154  // constructor and lifetime issues. Let the helper decide the actual
155  // name of the file given the prefix.
156  //
157  AsciiTraceHelper asciiTraceHelper;
158 
159  std::string filename;
160  if (explicitFilename)
161  {
162  filename = prefix;
163  }
164  else
165  {
166  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
167  }
168 
169  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
170 
171  //
172  // The MacRx trace source provides our "r" event.
173  //
174  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<PointToPointNetDevice> (device, "MacRx", theStream);
175 
176  //
177  // The "+", '-', and 'd' events are driven by trace sources actually in the
178  // transmit queue.
179  //
180  Ptr<Queue<Packet> > queue = device->GetQueue ();
181  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue<Packet> > (queue, "Enqueue", theStream);
182  asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue<Packet> > (queue, "Drop", theStream);
183  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue<Packet> > (queue, "Dequeue", theStream);
184 
185  // PhyRxDrop trace source for "d" event
186  asciiTraceHelper.HookDefaultDropSinkWithoutContext<PointToPointNetDevice> (device, "PhyRxDrop", theStream);
187 
188  return;
189  }
190 
191  //
192  // If we are provided an OutputStreamWrapper, we are expected to use it, and
193  // to providd a context. We are free to come up with our own context if we
194  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
195  // compatibility and simplicity, we just use Config::Connect and let it deal
196  // with the context.
197  //
198  // Note that we are going to use the default trace sinks provided by the
199  // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
200  // but the default trace sinks are actually publicly available static
201  // functions that are always there waiting for just such a case.
202  //
203  uint32_t nodeid = nd->GetNode ()->GetId ();
204  uint32_t deviceid = nd->GetIfIndex ();
205  std::ostringstream oss;
206 
207  oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
209 
210  oss.str ("");
211  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
213 
214  oss.str ("");
215  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Dequeue";
217 
218  oss.str ("");
219  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Drop";
221 
222  oss.str ("");
223  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/PhyRxDrop";
225 }
226 
229 {
230  NS_ASSERT (c.GetN () == 2);
231  return Install (c.Get (0), c.Get (1));
232 }
233 
236 {
237  NetDeviceContainer container;
238 
240  devA->SetAddress (Mac48Address::Allocate ());
241  a->AddDevice (devA);
243  devA->SetQueue (queueA);
245  devB->SetAddress (Mac48Address::Allocate ());
246  b->AddDevice (devB);
248  devB->SetQueue (queueB);
249  // Aggregate NetDeviceQueueInterface objects
250  Ptr<NetDeviceQueueInterface> ndqiA = CreateObject<NetDeviceQueueInterface> ();
251  ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
252  devA->AggregateObject (ndqiA);
253  Ptr<NetDeviceQueueInterface> ndqiB = CreateObject<NetDeviceQueueInterface> ();
254  ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
255  devB->AggregateObject (ndqiB);
256 
258 
259  // If MPI is enabled, we need to see if both nodes have the same system id
260  // (rank), and the rank is the same as this instance. If both are true,
261  // use a normal p2p channel, otherwise use a remote channel
262 #ifdef NS3_MPI
263  bool useNormalChannel = true;
265  {
266  uint32_t n1SystemId = a->GetSystemId ();
267  uint32_t n2SystemId = b->GetSystemId ();
268  uint32_t currSystemId = MpiInterface::GetSystemId ();
269  if (n1SystemId != currSystemId || n2SystemId != currSystemId)
270  {
271  useNormalChannel = false;
272  }
273  }
274  if (useNormalChannel)
275  {
277  }
278  else
279  {
280  channel = m_remoteChannelFactory.Create<PointToPointRemoteChannel> ();
281  Ptr<MpiReceiver> mpiRecA = CreateObject<MpiReceiver> ();
282  Ptr<MpiReceiver> mpiRecB = CreateObject<MpiReceiver> ();
283  mpiRecA->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devA));
284  mpiRecB->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devB));
285  devA->AggregateObject (mpiRecA);
286  devB->AggregateObject (mpiRecB);
287  }
288 #else
290 #endif
291 
292  devA->Attach (channel);
293  devB->Attach (channel);
294  container.Add (devA);
295  container.Add (devB);
296 
297  return container;
298 }
299 
302 {
303  Ptr<Node> b = Names::Find<Node> (bName);
304  return Install (a, b);
305 }
306 
309 {
310  Ptr<Node> a = Names::Find<Node> (aName);
311  return Install (a, b);
312 }
313 
315 PointToPointHelper::Install (std::string aName, std::string bName)
316 {
317  Ptr<Node> a = Names::Find<Node> (aName);
318  Ptr<Node> b = Names::Find<Node> (bName);
319  return Install (a, b);
320 }
321 
322 } // 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()
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:918
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()
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