A Discrete-Event Network Simulator
API
csma-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #include "csma-helper.h"
21 
22 #include "ns3/abort.h"
23 #include "ns3/config.h"
24 #include "ns3/csma-channel.h"
25 #include "ns3/csma-net-device.h"
26 #include "ns3/log.h"
27 #include "ns3/names.h"
28 #include "ns3/net-device-queue-interface.h"
29 #include "ns3/object-factory.h"
30 #include "ns3/packet.h"
31 #include "ns3/simulator.h"
32 #include "ns3/trace-helper.h"
33 
34 #include <string>
35 
36 namespace ns3
37 {
38 
39 NS_LOG_COMPONENT_DEFINE("CsmaHelper");
40 
42 {
43  m_queueFactory.SetTypeId("ns3::DropTailQueue<Packet>");
44  m_deviceFactory.SetTypeId("ns3::CsmaNetDevice");
45  m_channelFactory.SetTypeId("ns3::CsmaChannel");
46  m_enableFlowControl = true;
47 }
48 
49 void
51 {
52  m_deviceFactory.Set(n1, v1);
53 }
54 
55 void
57 {
58  m_channelFactory.Set(n1, v1);
59 }
60 
61 void
63 {
64  m_enableFlowControl = false;
65 }
66 
67 void
68 CsmaHelper::EnablePcapInternal(std::string prefix,
69  Ptr<NetDevice> nd,
70  bool promiscuous,
71  bool explicitFilename)
72 {
73  //
74  // All of the Pcap enable functions vector through here including the ones
75  // that are wandering through all of devices on perhaps all of the nodes in
76  // the system. We can only deal with devices of type CsmaNetDevice.
77  //
78  Ptr<CsmaNetDevice> device = nd->GetObject<CsmaNetDevice>();
79  if (!device)
80  {
81  NS_LOG_INFO("CsmaHelper::EnablePcapInternal(): Device "
82  << device << " not of type ns3::CsmaNetDevice");
83  return;
84  }
85 
86  PcapHelper pcapHelper;
87 
88  std::string filename;
89  if (explicitFilename)
90  {
91  filename = prefix;
92  }
93  else
94  {
95  filename = pcapHelper.GetFilenameFromDevice(prefix, device);
96  }
97 
99  pcapHelper.CreateFile(filename, std::ios::out, PcapHelper::DLT_EN10MB);
100  if (promiscuous)
101  {
102  pcapHelper.HookDefaultSink<CsmaNetDevice>(device, "PromiscSniffer", file);
103  }
104  else
105  {
106  pcapHelper.HookDefaultSink<CsmaNetDevice>(device, "Sniffer", file);
107  }
108 }
109 
110 void
112  std::string prefix,
113  Ptr<NetDevice> nd,
114  bool explicitFilename)
115 {
116  //
117  // All of the ascii enable functions vector through here including the ones
118  // that are wandering through all of devices on perhaps all of the nodes in
119  // the system. We can only deal with devices of type CsmaNetDevice.
120  //
121  Ptr<CsmaNetDevice> device = nd->GetObject<CsmaNetDevice>();
122  if (!device)
123  {
124  NS_LOG_INFO("CsmaHelper::EnableAsciiInternal(): Device "
125  << device << " not of type ns3::CsmaNetDevice");
126  return;
127  }
128 
129  //
130  // Our default trace sinks are going to use packet printing, so we have to
131  // make sure that is turned on.
132  //
134 
135  //
136  // If we are not provided an OutputStreamWrapper, we are expected to create
137  // one using the usual trace filename conventions and do a Hook*WithoutContext
138  // since there will be one file per context and therefore the context would
139  // be redundant.
140  //
141  if (!stream)
142  {
143  //
144  // Set up an output stream object to deal with private ofstream copy
145  // constructor and lifetime issues. Let the helper decide the actual
146  // name of the file given the prefix.
147  //
148  AsciiTraceHelper asciiTraceHelper;
149 
150  std::string filename;
151  if (explicitFilename)
152  {
153  filename = prefix;
154  }
155  else
156  {
157  filename = asciiTraceHelper.GetFilenameFromDevice(prefix, device);
158  }
159 
160  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream(filename);
161 
162  //
163  // The MacRx trace source provides our "r" event.
164  //
165  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<CsmaNetDevice>(device,
166  "MacRx",
167  theStream);
168 
169  //
170  // The "+", '-', and 'd' events are driven by trace sources actually in the
171  // transmit queue.
172  //
173  Ptr<Queue<Packet>> queue = device->GetQueue();
174  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue<Packet>>(queue,
175  "Enqueue",
176  theStream);
177  asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue<Packet>>(queue, "Drop", theStream);
178  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue<Packet>>(queue,
179  "Dequeue",
180  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
202  << "/$ns3::CsmaNetDevice/MacRx";
203  Config::Connect(oss.str(),
205 
206  oss.str("");
207  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
208  << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
209  Config::Connect(oss.str(),
211 
212  oss.str("");
213  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
214  << "/$ns3::CsmaNetDevice/TxQueue/Dequeue";
215  Config::Connect(oss.str(),
217 
218  oss.str("");
219  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
220  << "/$ns3::CsmaNetDevice/TxQueue/Drop";
221  Config::Connect(oss.str(),
223 }
224 
227 {
229  return Install(node, channel);
230 }
231 
233 CsmaHelper::Install(std::string nodeName) const
234 {
235  Ptr<Node> node = Names::Find<Node>(nodeName);
236  return Install(node);
237 }
238 
241 {
242  return NetDeviceContainer(InstallPriv(node, channel));
243 }
244 
246 CsmaHelper::Install(Ptr<Node> node, std::string channelName) const
247 {
248  Ptr<CsmaChannel> channel = Names::Find<CsmaChannel>(channelName);
249  return NetDeviceContainer(InstallPriv(node, channel));
250 }
251 
253 CsmaHelper::Install(std::string nodeName, Ptr<CsmaChannel> channel) const
254 {
255  Ptr<Node> node = Names::Find<Node>(nodeName);
256  return NetDeviceContainer(InstallPriv(node, channel));
257 }
258 
260 CsmaHelper::Install(std::string nodeName, std::string channelName) const
261 {
262  Ptr<Node> node = Names::Find<Node>(nodeName);
263  Ptr<CsmaChannel> channel = Names::Find<CsmaChannel>(channelName);
264  return NetDeviceContainer(InstallPriv(node, channel));
265 }
266 
269 {
271 
272  return Install(c, channel);
273 }
274 
277 {
278  NetDeviceContainer devs;
279 
280  for (auto i = c.Begin(); i != c.End(); i++)
281  {
282  devs.Add(InstallPriv(*i, channel));
283  }
284 
285  return devs;
286 }
287 
289 CsmaHelper::Install(const NodeContainer& c, std::string channelName) const
290 {
291  Ptr<CsmaChannel> channel = Names::Find<CsmaChannel>(channelName);
292  return Install(c, channel);
293 }
294 
295 int64_t
297 {
298  int64_t currentStream = stream;
299  Ptr<NetDevice> netDevice;
300  for (auto i = c.Begin(); i != c.End(); ++i)
301  {
302  netDevice = (*i);
303  Ptr<CsmaNetDevice> csma = DynamicCast<CsmaNetDevice>(netDevice);
304  if (csma)
305  {
306  currentStream += csma->AssignStreams(currentStream);
307  }
308  }
309  return (currentStream - stream);
310 }
311 
314 {
316  device->SetAddress(Mac48Address::Allocate());
317  node->AddDevice(device);
319  device->SetQueue(queue);
320  device->Attach(channel);
322  {
323  // Aggregate a NetDeviceQueueInterface object
324  Ptr<NetDeviceQueueInterface> ndqi = CreateObject<NetDeviceQueueInterface>();
325  ndqi->GetTxQueue(0)->ConnectQueueTraces(queue);
326  device->AggregateObject(ndqi);
327  }
328  return device;
329 }
330 
331 } // namespace ns3
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
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:534
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 ...
Definition: trace-helper.h:505
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:592
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 ...
Definition: trace-helper.h:563
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:70
Csma Channel.
Definition: csma-channel.h:92
ObjectFactory m_channelFactory
factory for the channel
Definition: csma-helper.h:259
void SetDeviceAttribute(std::string n1, const AttributeValue &v1)
Definition: csma-helper.cc:50
void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename) override
Enable ascii trace output on the indicated net device.
Definition: csma-helper.cc:111
bool m_enableFlowControl
whether to enable flow control
Definition: csma-helper.h:260
Ptr< NetDevice > InstallPriv(Ptr< Node > node, Ptr< CsmaChannel > channel) const
This method creates an ns3::CsmaNetDevice with the attributes configured by CsmaHelper::SetDeviceAttr...
Definition: csma-helper.cc:313
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
Definition: csma-helper.cc:56
CsmaHelper()
Construct a CsmaHelper.
Definition: csma-helper.cc:41
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: csma-helper.cc:296
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
void DisableFlowControl()
Disable flow control only if you know what you are doing.
Definition: csma-helper.cc:62
ObjectFactory m_queueFactory
factory for the queues
Definition: csma-helper.h:257
void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename) override
Enable pcap output on the indicated net device.
Definition: csma-helper.cc:68
ObjectFactory m_deviceFactory
factory for the NetDevices
Definition: csma-helper.h:258
A Device for a Csma Network Link.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
static Mac48Address Allocate()
Allocate a new Mac48Address.
holds a vector of ns3::NetDevice pointers
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
static void EnablePrinting()
Enable printing packets metadata.
Definition: packet.cc:596
Manage pcap files for device models.
Definition: trace-helper.h:40
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:79
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 HookDefaultSink(Ptr< T > object, std::string traceName, Ptr< PcapFileWrapper > file)
Hook a trace source to the default trace sink.
Definition: trace-helper.h:158
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Template class for packet Queues.
Definition: queue.h:268
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:974
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
Every class exported by the ns3 library is enclosed in the ns3 namespace.
csma
Definition: second.py:63
channel
Definition: third.py:88