A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
point-to-point-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "ns3/abort.h"
10#include "ns3/config.h"
11#include "ns3/log.h"
12#include "ns3/names.h"
13#include "ns3/net-device-queue-interface.h"
14#include "ns3/packet.h"
15#include "ns3/point-to-point-channel.h"
16#include "ns3/point-to-point-net-device.h"
17#include "ns3/simulator.h"
18
19#ifdef NS3_MPI
20#include "ns3/mpi-interface.h"
21#include "ns3/mpi-receiver.h"
22#include "ns3/point-to-point-remote-channel.h"
23#endif
24
26
27#include "ns3/trace-helper.h"
28
29namespace ns3
30{
31
32NS_LOG_COMPONENT_DEFINE("PointToPointHelper");
33
35{
36 m_queueFactory.SetTypeId("ns3::DropTailQueue<Packet>");
37 m_deviceFactory.SetTypeId("ns3::PointToPointNetDevice");
38 m_channelFactory.SetTypeId("ns3::PointToPointChannel");
40}
41
42void
44{
45 m_deviceFactory.Set(n1, v1);
46}
47
48void
50{
51 m_channelFactory.Set(n1, v1);
52}
53
54void
59
60void
63 bool promiscuous,
64 bool explicitFilename)
65{
66 //
67 // All of the Pcap enable functions vector through here including the ones
68 // that are wandering through all of devices on perhaps all of the nodes in
69 // the system. We can only deal with devices of type PointToPointNetDevice.
70 //
71 Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice>();
72 if (!device)
73 {
74 NS_LOG_INFO("Device " << device << " not of type ns3::PointToPointNetDevice");
75 return;
76 }
77
78 PcapHelper pcapHelper;
79
80 std::string filename;
81 if (explicitFilename)
82 {
83 filename = prefix;
84 }
85 else
86 {
87 filename = pcapHelper.GetFilenameFromDevice(prefix, device);
88 }
89
90 Ptr<PcapFileWrapper> file = pcapHelper.CreateFile(filename, std::ios::out, PcapHelper::DLT_PPP);
91 pcapHelper.HookDefaultSink<PointToPointNetDevice>(device, "PromiscSniffer", file);
92}
93
94void
96 std::string prefix,
98 bool explicitFilename)
99{
100 //
101 // All of the ascii enable functions vector through here including the ones
102 // that are wandering through all of devices on perhaps all of the nodes in
103 // the system. We can only deal with devices of type PointToPointNetDevice.
104 //
105 Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice>();
106 if (!device)
107 {
108 NS_LOG_INFO("Device " << device << " not of type ns3::PointToPointNetDevice");
109 return;
110 }
111
112 //
113 // Our default trace sinks are going to use packet printing, so we have to
114 // make sure that is turned on.
115 //
117
118 //
119 // If we are not provided an OutputStreamWrapper, we are expected to create
120 // one using the usual trace filename conventions and do a Hook*WithoutContext
121 // since there will be one file per context and therefore the context would
122 // be redundant.
123 //
124 if (!stream)
125 {
126 //
127 // Set up an output stream object to deal with private ofstream copy
128 // constructor and lifetime issues. Let the helper decide the actual
129 // name of the file given the prefix.
130 //
131 AsciiTraceHelper asciiTraceHelper;
132
133 std::string filename;
134 if (explicitFilename)
135 {
136 filename = prefix;
137 }
138 else
139 {
140 filename = asciiTraceHelper.GetFilenameFromDevice(prefix, device);
141 }
142
143 Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream(filename);
144
145 //
146 // The MacRx trace source provides our "r" event.
147 //
149 "MacRx",
150 theStream);
151
152 //
153 // The "+", '-', and 'd' events are driven by trace sources actually in the
154 // transmit queue.
155 //
156 Ptr<Queue<Packet>> queue = device->GetQueue();
158 "Enqueue",
159 theStream);
160 asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue<Packet>>(queue, "Drop", theStream);
162 "Dequeue",
163 theStream);
164
165 // PhyRxDrop trace source for "d" event
167 "PhyRxDrop",
168 theStream);
169
170 return;
171 }
172
173 //
174 // If we are provided an OutputStreamWrapper, we are expected to use it, and
175 // to providd a context. We are free to come up with our own context if we
176 // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
177 // compatibility and simplicity, we just use Config::Connect and let it deal
178 // with the context.
179 //
180 // Note that we are going to use the default trace sinks provided by the
181 // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
182 // but the default trace sinks are actually publicly available static
183 // functions that are always there waiting for just such a case.
184 //
185 uint32_t nodeid = nd->GetNode()->GetId();
186 uint32_t deviceid = nd->GetIfIndex();
187 std::ostringstream oss;
188
189 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
190 << "/$ns3::PointToPointNetDevice/MacRx";
191 Config::Connect(oss.str(),
193
194 oss.str("");
195 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
196 << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
197 Config::Connect(oss.str(),
199
200 oss.str("");
201 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
202 << "/$ns3::PointToPointNetDevice/TxQueue/Dequeue";
203 Config::Connect(oss.str(),
205
206 oss.str("");
207 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
208 << "/$ns3::PointToPointNetDevice/TxQueue/Drop";
209 Config::Connect(oss.str(),
211
212 oss.str("");
213 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
214 << "/$ns3::PointToPointNetDevice/PhyRxDrop";
215 Config::Connect(oss.str(),
217}
218
221{
222 NS_ASSERT(c.GetN() == 2);
223 return Install(c.Get(0), c.Get(1));
224}
225
228{
229 NetDeviceContainer container;
230
232 devA->SetAddress(Mac48Address::Allocate());
233 a->AddDevice(devA);
235 devA->SetQueue(queueA);
237 devB->SetAddress(Mac48Address::Allocate());
238 b->AddDevice(devB);
240 devB->SetQueue(queueB);
242 {
243 // Aggregate NetDeviceQueueInterface objects
245 ndqiA->GetTxQueue(0)->ConnectQueueTraces(queueA);
246 devA->AggregateObject(ndqiA);
248 ndqiB->GetTxQueue(0)->ConnectQueueTraces(queueB);
249 devB->AggregateObject(ndqiB);
250 }
251
252 Ptr<PointToPointChannel> channel = nullptr;
253
254 // If MPI is enabled, we need to see if both nodes have the same system id
255 // (rank), and the rank is the same as this instance. If both are true,
256 // use a normal p2p channel, otherwise use a remote channel
257#ifdef NS3_MPI
258 bool useNormalChannel = true;
260 {
261 uint32_t n1SystemId = a->GetSystemId();
262 uint32_t n2SystemId = b->GetSystemId();
263 uint32_t currSystemId = MpiInterface::GetSystemId();
264 if (n1SystemId != currSystemId || n2SystemId != currSystemId)
265 {
266 useNormalChannel = false;
267 }
268 }
269 if (useNormalChannel)
270 {
271 m_channelFactory.SetTypeId("ns3::PointToPointChannel");
272 channel = m_channelFactory.Create<PointToPointChannel>();
273 }
274 else
275 {
276 m_channelFactory.SetTypeId("ns3::PointToPointRemoteChannel");
280 mpiRecA->SetReceiveCallback(MakeCallback(&PointToPointNetDevice::Receive, devA));
281 mpiRecB->SetReceiveCallback(MakeCallback(&PointToPointNetDevice::Receive, devB));
282 devA->AggregateObject(mpiRecA);
283 devB->AggregateObject(mpiRecB);
284 }
285#else
286 channel = m_channelFactory.Create<PointToPointChannel>();
287#endif
288
289 devA->Attach(channel);
290 devB->Attach(channel);
291 container.Add(devA);
292 container.Add(devB);
293
294 return container;
295}
296
299{
300 Ptr<Node> b = Names::Find<Node>(bName);
301 return Install(a, b);
302}
303
306{
307 Ptr<Node> a = Names::Find<Node>(aName);
308 return Install(a, b);
309}
310
312PointToPointHelper::Install(std::string aName, std::string bName)
313{
314 Ptr<Node> a = Names::Find<Node>(aName);
315 Ptr<Node> b = Names::Find<Node>(bName);
316 return Install(a, b);
317}
318
319} // namespace ns3
Manage ASCII trace files for device models.
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...
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...
static void DefaultDropSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Drop default trace sink.
static void DefaultReceiveSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Receive default trace sink.
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
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 ...
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 ...
static void DefaultEnqueueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Enqueue default trace sink.
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 ...
static void DefaultDequeueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Dequeue default trace sink.
Hold a value for an Attribute.
Definition attribute.h:59
static Mac48Address Allocate()
Allocate a new Mac48Address.
static bool IsEnabled()
Returns enabled state of parallel environment.
static uint32_t GetSystemId()
Get the id number of this rank.
static Ptr< T > Find(std::string path)
Given a name path string, look to see if there's an object in the system with that associated to it.
Definition names.h:443
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
static void EnablePrinting()
Enable printing packets metadata.
Definition packet.cc:585
Manage pcap files for device models.
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.
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.
void HookDefaultSink(Ptr< T > object, std::string traceName, Ptr< PcapFileWrapper > file)
Hook a trace source to the default trace sink.
Simple Point To Point Channel.
ObjectFactory m_channelFactory
Channel Factory.
PointToPointHelper()
Create a PointToPointHelper to make life easier when creating point to point networks.
bool m_enableFlowControl
whether to enable flow control
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void DisableFlowControl()
Disable flow control only if you know what you are doing.
void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename) override
Enable pcap output the indicated net device.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
ObjectFactory m_queueFactory
Queue Factory.
ObjectFactory m_deviceFactory
Device Factory.
NetDeviceContainer Install(NodeContainer c)
void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename) override
Enable ascii trace output on the indicated net device.
A Device for a Point to Point Network Link.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
void Receive(Ptr< Packet > p)
Receive a packet from a connected PointToPointChannel.
A Remote Point-To-Point Channel.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
Template class for packet Queues.
Definition queue.h:257
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:970
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684