A Discrete-Event Network Simulator
API
lr-wpan-helper.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 The Boeing Company
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  * Authors:
19  * Gary Pei <guangyu.pei@boeing.com>
20  * Tom Henderson <thomas.r.henderson@boeing.com>
21  */
22 #include "lr-wpan-helper.h"
23 #include <ns3/lr-wpan-csmaca.h>
24 #include <ns3/lr-wpan-error-model.h>
25 #include <ns3/lr-wpan-net-device.h>
26 #include <ns3/mobility-model.h>
27 #include <ns3/single-model-spectrum-channel.h>
28 #include <ns3/multi-model-spectrum-channel.h>
29 #include <ns3/propagation-loss-model.h>
30 #include <ns3/propagation-delay-model.h>
31 #include <ns3/log.h>
32 #include "ns3/names.h"
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("LrWpanHelper");
37 
44 static void
47  std::string context,
49 {
50  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
51 }
52 
58 static void
62 {
63  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
64 }
65 
67 {
68  m_channel = CreateObject<SingleModelSpectrumChannel> ();
69 
70  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> ();
71  m_channel->AddPropagationLossModel (lossModel);
72 
73  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
74  m_channel->SetPropagationDelayModel (delayModel);
75 }
76 
77 LrWpanHelper::LrWpanHelper (bool useMultiModelSpectrumChannel)
78 {
79  if (useMultiModelSpectrumChannel)
80  {
81  m_channel = CreateObject<MultiModelSpectrumChannel> ();
82  }
83  else
84  {
85  m_channel = CreateObject<SingleModelSpectrumChannel> ();
86  }
87  Ptr<LogDistancePropagationLossModel> lossModel = CreateObject<LogDistancePropagationLossModel> ();
88  m_channel->AddPropagationLossModel (lossModel);
89 
90  Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
91  m_channel->SetPropagationDelayModel (delayModel);
92 }
93 
95 {
96  m_channel->Dispose ();
97  m_channel = 0;
98 }
99 
100 void
102 {
105  LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_ALL);
106  LogComponentEnable ("LrWpanErrorModel", LOG_LEVEL_ALL);
107  LogComponentEnable ("LrWpanInterferenceHelper", LOG_LEVEL_ALL);
108  LogComponentEnable ("LrWpanMac", LOG_LEVEL_ALL);
109  LogComponentEnable ("LrWpanNetDevice", LOG_LEVEL_ALL);
110  LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL);
111  LogComponentEnable ("LrWpanSpectrumSignalParameters", LOG_LEVEL_ALL);
112  LogComponentEnable ("LrWpanSpectrumValueHelper", LOG_LEVEL_ALL);
113 }
114 
115 std::string
117 {
118  switch (e)
119  {
121  return std::string ("BUSY");
123  return std::string ("BUSY_RX");
125  return std::string ("BUSY_TX");
127  return std::string ("FORCE_TRX_OFF");
129  return std::string ("IDLE");
131  return std::string ("INVALID_PARAMETER");
133  return std::string ("RX_ON");
135  return std::string ("SUCCESS");
137  return std::string ("TRX_OFF");
139  return std::string ("TX_ON");
141  return std::string ("UNSUPPORTED_ATTRIBUTE");
143  return std::string ("READ_ONLY");
145  return std::string ("UNSPECIFIED");
146  default:
147  return std::string ("INVALID");
148  }
149 }
150 
151 std::string
153 {
154  switch (e)
155  {
156  case MAC_IDLE:
157  return std::string ("MAC_IDLE");
159  return std::string ("CHANNEL_ACCESS_FAILURE");
160  case CHANNEL_IDLE:
161  return std::string ("CHANNEL_IDLE");
162  case SET_PHY_TX_ON:
163  return std::string ("SET_PHY_TX_ON");
164  default:
165  return std::string ("INVALID");
166  }
167 }
168 
169 void
171 {
172  phy->SetMobility (m);
173 }
174 
177 {
179  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
180  {
181  Ptr<Node> node = *i;
182 
183  Ptr<LrWpanNetDevice> netDevice = CreateObject<LrWpanNetDevice> ();
184  netDevice->SetChannel (m_channel);
185  node->AddDevice (netDevice);
186  netDevice->SetNode (node);
187  // \todo add the capability to change short address, extended
188  // address and panId. Right now they are hardcoded in LrWpanMac::LrWpanMac ()
189  devices.Add (netDevice);
190  }
191  return devices;
192 }
193 
194 
197 {
198  return m_channel;
199 }
200 
201 void
203 {
204  m_channel = channel;
205 }
206 
207 void
208 LrWpanHelper::SetChannel (std::string channelName)
209 {
210  Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel> (channelName);
211  m_channel = channel;
212 }
213 
214 
215 int64_t
217 {
218  int64_t currentStream = stream;
219  Ptr<NetDevice> netDevice;
220  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
221  {
222  netDevice = (*i);
223  Ptr<LrWpanNetDevice> lrwpan = DynamicCast<LrWpanNetDevice> (netDevice);
224  if (lrwpan)
225  {
226  currentStream += lrwpan->AssignStreams (currentStream);
227  }
228  }
229  return (currentStream - stream);
230 }
231 
232 void
234 {
236  uint16_t id = 1;
237  uint8_t idBuf[2];
238 
239  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); i++)
240  {
241  Ptr<LrWpanNetDevice> device = DynamicCast<LrWpanNetDevice> (*i);
242  if (device)
243  {
244  idBuf[0] = (id >> 8) & 0xff;
245  idBuf[1] = (id >> 0) & 0xff;
247  address.CopyFrom (idBuf);
248 
249  device->GetMac ()->SetPanId (panId);
250  device->GetMac ()->SetShortAddress (address);
251  id++;
252  }
253  }
254  return;
255 }
256 
262 static void
264 {
265  file->Write (Simulator::Now (), packet);
266 }
267 
268 void
269 LrWpanHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
270 {
271  NS_LOG_FUNCTION (this << prefix << nd << promiscuous << explicitFilename);
272  //
273  // All of the Pcap enable functions vector through here including the ones
274  // that are wandering through all of devices on perhaps all of the nodes in
275  // the system.
276  //
277 
278  // In the future, if we create different NetDevice types, we will
279  // have to switch on each type below and insert into the right
280  // NetDevice type
281  //
282  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
283  if (device == 0)
284  {
285  NS_LOG_INFO ("LrWpanHelper::EnablePcapInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
286  return;
287  }
288 
289  PcapHelper pcapHelper;
290 
291  std::string filename;
292  if (explicitFilename)
293  {
294  filename = prefix;
295  }
296  else
297  {
298  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
299  }
300 
301  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
303 
304  if (promiscuous == true)
305  {
306  device->GetMac ()->TraceConnectWithoutContext ("PromiscSniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
307 
308  }
309  else
310  {
311  device->GetMac ()->TraceConnectWithoutContext ("Sniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
312  }
313 }
314 
315 void
318  std::string prefix,
319  Ptr<NetDevice> nd,
320  bool explicitFilename)
321 {
322  uint32_t nodeid = nd->GetNode ()->GetId ();
323  uint32_t deviceid = nd->GetIfIndex ();
324  std::ostringstream oss;
325 
326  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
327  if (device == 0)
328  {
329  NS_LOG_INFO ("LrWpanHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
330  return;
331  }
332 
333  //
334  // Our default trace sinks are going to use packet printing, so we have to
335  // make sure that is turned on.
336  //
338 
339  //
340  // If we are not provided an OutputStreamWrapper, we are expected to create
341  // one using the usual trace filename conventions and do a Hook*WithoutContext
342  // since there will be one file per context and therefore the context would
343  // be redundant.
344  //
345  if (stream == 0)
346  {
347  //
348  // Set up an output stream object to deal with private ofstream copy
349  // constructor and lifetime issues. Let the helper decide the actual
350  // name of the file given the prefix.
351  //
352  AsciiTraceHelper asciiTraceHelper;
353 
354  std::string filename;
355  if (explicitFilename)
356  {
357  filename = prefix;
358  }
359  else
360  {
361  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
362  }
363 
364  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
365 
366  // Ascii traces typically have "+", '-", "d", "r", and sometimes "t"
367  // The Mac and Phy objects have the trace sources for these
368  //
369 
370  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<LrWpanMac> (device->GetMac (), "MacRx", theStream);
371 
372  device->GetMac ()->TraceConnectWithoutContext ("MacTx", MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithoutContext, theStream));
373 
374  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<LrWpanMac> (device->GetMac (), "MacTxEnqueue", theStream);
375  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<LrWpanMac> (device->GetMac (), "MacTxDequeue", theStream);
376  asciiTraceHelper.HookDefaultDropSinkWithoutContext<LrWpanMac> (device->GetMac (), "MacTxDrop", theStream);
377 
378  return;
379  }
380 
381  //
382  // If we are provided an OutputStreamWrapper, we are expected to use it, and
383  // to provide a context. We are free to come up with our own context if we
384  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
385  // compatibility and simplicity, we just use Config::Connect and let it deal
386  // with the context.
387  //
388  // Note that we are going to use the default trace sinks provided by the
389  // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
390  // but the default trace sinks are actually publicly available static
391  // functions that are always there waiting for just such a case.
392  //
393 
394 
395  oss.str ("");
396  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacRx";
397  device->GetMac ()->TraceConnect ("MacRx", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
398 
399  oss.str ("");
400  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTx";
401  device->GetMac ()->TraceConnect ("MacTx", oss.str (), MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithContext, stream));
402 
403  oss.str ("");
404  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxEnqueue";
405  device->GetMac ()->TraceConnect ("MacTxEnqueue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
406 
407  oss.str ("");
408  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDequeue";
409  device->GetMac ()->TraceConnect ("MacTxDequeue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
410 
411  oss.str ("");
412  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDrop";
413  device->GetMac ()->TraceConnect ("MacTxDrop", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
414 
415 }
416 
417 } // namespace ns3
418 
NetDeviceContainer Install(NodeContainer c)
Install a LrWpanNetDevice and the associated structures (e.g., channel) in the nodes.
Manage ASCII trace files for device models.
Definition: trace-helper.h:161
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
static void DefaultEnqueueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Enqueue default trace sink.
Class that implements the LR-WPAN Mac state machine.
Definition: lr-wpan-mac.h:222
static std::string LrWpanPhyEnumerationPrinter(LrWpanPhyEnumeration e)
Transform the LrWpanPhyEnumeration enumeration into a printable string.
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
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
Manage pcap files for device models.
Definition: trace-helper.h:38
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:74
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
static void DefaultDropSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Drop default trace sink.
static std::string LrWpanMacStatePrinter(LrWpanMacState e)
Transform the LrWpanMacState enumeration into a printable string.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
void AssociateToPan(NetDeviceContainer c, uint16_t panId)
Associate the nodes to the same PAN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:280
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. ...
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
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
Network layer to device interface.
channel
Definition: third.py:85
phy
Definition: third.py:86
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
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:369
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:572
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
holds a vector of ns3::NetDevice pointers
SET_PHY_TX_ON.
Definition: lr-wpan-mac.h:75
static void AsciiLrWpanMacTransmitSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p)
Output an ascii line representing the Transmit event (without context)
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
virtual void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename)
Enable pcap output on the indicated net device.
static void DefaultReceiveSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Receive default trace sink.
Ptr< SpectrumChannel > m_channel
channel to be used for the devices
static void AsciiLrWpanMacTransmitSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p)
Output an ascii line representing the Transmit event (with context)
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:393
Prefix all trace prints with simulation time.
Definition: log.h:118
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.
keep track of a set of node pointers.
address
Definition: first.py:37
LrWpanHelper(void)
Create a LrWpan helper in an empty state.
This class can contain 16 bit addresses.
Definition: mac16-address.h:41
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
virtual void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename)
Enable ascii trace output on the indicated net device.
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 SetChannel(Ptr< SpectrumChannel > channel)
Set the channel associated to this helper.
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:73
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:128
Prefix all trace prints with function.
Definition: log.h:117
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
LrWpanMacState
MAC states.
Definition: lr-wpan-mac.h:67
Ptr< SpectrumChannel > GetChannel(void)
Get the channel associated to this helper.
Print everything.
Definition: log.h:115
void AddMobility(Ptr< LrWpanPhy > phy, Ptr< MobilityModel > m)
Add mobility model to a physical device.
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:105
devices
Definition: first.py:32
virtual ~LrWpanHelper(void)
void EnableLogComponents(void)
Helper to enable all LrWpan log components with one statement.
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
static void PcapSniffLrWpan(Ptr< PcapFileWrapper > file, Ptr< const Packet > packet)
Write a packet in a PCAP file.
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
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
MAC_IDLE.
Definition: lr-wpan-mac.h:69