A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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/propagation-loss-model.h>
29 #include <ns3/log.h>
30 
31 NS_LOG_COMPONENT_DEFINE ("LrWpanHelper");
32 
33 namespace ns3 {
34 
41 static void
44  std::string context,
46 {
47  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
48 }
49 
55 static void
59 {
60  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
61 }
62 
64 {
65  m_channel = CreateObject<SingleModelSpectrumChannel> ();
66  Ptr<LogDistancePropagationLossModel> model = CreateObject<LogDistancePropagationLossModel> ();
67  m_channel->AddPropagationLossModel (model);
68 }
69 
71 {
72  m_channel->Dispose ();
73  m_channel = 0;
74 }
75 
76 void
78 {
81  LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_ALL);
82  LogComponentEnable ("LrWpanErrorModel", LOG_LEVEL_ALL);
83  LogComponentEnable ("LrWpanInterferenceHelper", LOG_LEVEL_ALL);
84  LogComponentEnable ("LrWpanMac", LOG_LEVEL_ALL);
85  LogComponentEnable ("LrWpanNetDevice", LOG_LEVEL_ALL);
86  LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL);
87  LogComponentEnable ("LrWpanSpectrumSignalParameters", LOG_LEVEL_ALL);
88  LogComponentEnable ("LrWpanSpectrumValueHelper", LOG_LEVEL_ALL);
89 }
90 
91 std::string
93 {
94  switch (e)
95  {
97  return std::string ("BUSY");
99  return std::string ("BUSY_RX");
101  return std::string ("BUSY_TX");
103  return std::string ("FORCE_TRX_OFF");
105  return std::string ("IDLE");
107  return std::string ("INVALID_PARAMETER");
109  return std::string ("RX_ON");
111  return std::string ("SUCCESS");
113  return std::string ("TRX_OFF");
115  return std::string ("TX_ON");
117  return std::string ("UNSUPPORTED_ATTRIBUTE");
119  return std::string ("READ_ONLY");
121  return std::string ("UNSPECIFIED");
122  default:
123  return std::string ("INVALID");
124  }
125 }
126 
127 std::string
129 {
130  switch (e)
131  {
132  case MAC_IDLE:
133  return std::string ("MAC_IDLE");
135  return std::string ("CHANNEL_ACCESS_FAILURE");
136  case CHANNEL_IDLE:
137  return std::string ("CHANNEL_IDLE");
138  case SET_PHY_TX_ON:
139  return std::string ("SET_PHY_TX_ON");
140  default:
141  return std::string ("INVALID");
142  }
143 }
144 
145 void
147 {
148  phy->SetMobility (m);
149 }
150 
153 {
155  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
156  {
157  Ptr<Node> node = *i;
158 
159  Ptr<LrWpanNetDevice> netDevice = CreateObject<LrWpanNetDevice> ();
160  netDevice->SetChannel (m_channel);
161  node->AddDevice (netDevice);
162  netDevice->SetNode (node);
163  // \todo add the capability to change short address, extended
164  // address and panId. Right now they are hardcoded in LrWpanMac::LrWpanMac ()
165  devices.Add (netDevice);
166  }
167  return devices;
168 }
169 
170 int64_t
172 {
173  int64_t currentStream = stream;
174  Ptr<NetDevice> netDevice;
175  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
176  {
177  netDevice = (*i);
178  Ptr<LrWpanNetDevice> lrwpan = DynamicCast<LrWpanNetDevice> (netDevice);
179  if (lrwpan)
180  {
181  currentStream += lrwpan->AssignStreams (currentStream);
182  }
183  }
184  return (currentStream - stream);
185 }
186 
187 void
189 {
191  uint16_t id = 1;
192  uint8_t idBuf[2];
193 
194  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); i++)
195  {
196  Ptr<LrWpanNetDevice> device = DynamicCast<LrWpanNetDevice> (*i);
197  if (device)
198  {
199  idBuf[0] = (id >> 8) & 0xff;
200  idBuf[1] = (id >> 0) & 0xff;
202  address.CopyFrom (idBuf);
203 
204  device->GetMac ()->SetPanId (panId);
205  device->GetMac ()->SetShortAddress (address);
206  id++;
207  }
208  }
209  return;
210 }
211 
217 static void
219 {
220  file->Write (Simulator::Now (), packet);
221 }
222 
223 void
224 LrWpanHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
225 {
226  NS_LOG_FUNCTION (this << prefix << nd << promiscuous << explicitFilename);
227  //
228  // All of the Pcap enable functions vector through here including the ones
229  // that are wandering through all of devices on perhaps all of the nodes in
230  // the system.
231  //
232 
233  // In the future, if we create different NetDevice types, we will
234  // have to switch on each type below and insert into the right
235  // NetDevice type
236  //
237  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
238  if (device == 0)
239  {
240  NS_LOG_INFO ("LrWpanHelper::EnablePcapInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
241  return;
242  }
243 
244  PcapHelper pcapHelper;
245 
246  std::string filename;
247  if (explicitFilename)
248  {
249  filename = prefix;
250  }
251  else
252  {
253  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
254  }
255 
256  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
258 
259  if (promiscuous == true)
260  {
261  device->GetMac ()->TraceConnectWithoutContext ("PromiscSniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
262 
263  }
264  else
265  {
266  device->GetMac ()->TraceConnectWithoutContext ("Sniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
267  }
268 }
269 
270 void
273  std::string prefix,
274  Ptr<NetDevice> nd,
275  bool explicitFilename)
276 {
277  uint32_t nodeid = nd->GetNode ()->GetId ();
278  uint32_t deviceid = nd->GetIfIndex ();
279  std::ostringstream oss;
280 
281  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
282  if (device == 0)
283  {
284  NS_LOG_INFO ("LrWpanHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
285  return;
286  }
287 
288  //
289  // Our default trace sinks are going to use packet printing, so we have to
290  // make sure that is turned on.
291  //
293 
294  //
295  // If we are not provided an OutputStreamWrapper, we are expected to create
296  // one using the usual trace filename conventions and do a Hook*WithoutContext
297  // since there will be one file per context and therefore the context would
298  // be redundant.
299  //
300  if (stream == 0)
301  {
302  //
303  // Set up an output stream object to deal with private ofstream copy
304  // constructor and lifetime issues. Let the helper decide the actual
305  // name of the file given the prefix.
306  //
307  AsciiTraceHelper asciiTraceHelper;
308 
309  std::string filename;
310  if (explicitFilename)
311  {
312  filename = prefix;
313  }
314  else
315  {
316  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
317  }
318 
319  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
320 
321  // Ascii traces typically have "+", '-", "d", "r", and sometimes "t"
322  // The Mac and Phy objects have the trace sources for these
323  //
324 
325  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<LrWpanNetDevice> (device, "MacRx", theStream);
326 
327  device->GetMac ()->TraceConnectWithoutContext ("MacTx", MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithoutContext, theStream));
328 
329  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<LrWpanNetDevice> (device, "MacTxEnqueue", theStream);
330  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<LrWpanNetDevice> (device, "MacTxDequeue", theStream);
331  asciiTraceHelper.HookDefaultDropSinkWithoutContext<LrWpanNetDevice> (device, "MacTxDrop", theStream);
332 
333  return;
334  }
335 
336  //
337  // If we are provided an OutputStreamWrapper, we are expected to use it, and
338  // to provide a context. We are free to come up with our own context if we
339  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
340  // compatibility and simplicity, we just use Config::Connect and let it deal
341  // with the context.
342  //
343  // Note that we are going to use the default trace sinks provided by the
344  // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
345  // but the default trace sinks are actually publicly available static
346  // functions that are always there waiting for just such a case.
347  //
348 
349 
350  oss.str ("");
351  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacRx";
352  device->GetMac ()->TraceConnect ("MacRx", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
353 
354  oss.str ("");
355  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTx";
356  device->GetMac ()->TraceConnect ("MacTx", oss.str (), MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithContext, stream));
357 
358  oss.str ("");
359  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxEnqueue";
360  device->GetMac ()->TraceConnect ("MacTxEnqueue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
361 
362  oss.str ("");
363  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDequeue";
364  device->GetMac ()->TraceConnect ("MacTxDequeue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
365 
366  oss.str ("");
367  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDrop";
368  device->GetMac ()->TraceConnect ("MacTxDrop", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
369 
370 }
371 
372 } // namespace ns3
373 
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:342
NetDeviceContainer Install(NodeContainer c)
Install a LrWpanNetDevice and the associated structures (e.g., channel) in the nodes.
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
LrWpanMacState
MAC states.
Definition: lr-wpan-mac.h:62
Manage ASCII trace files for device models.
Definition: trace-helper.h:141
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
tuple devices
Definition: first.py:32
static void DefaultEnqueueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Enqueue default trace sink.
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, uint32_t dataLinkType, uint32_t snapLen=65535, int32_t tzCorrection=0)
Create and initialize a pcap file.
Definition: trace-helper.cc:49
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:463
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Manage pcap files for device models.
Definition: trace-helper.h:38
void Write(Time t, Ptr< const Packet > p)
Write the next packet to file.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1480
void CopyFrom(const uint8_t buffer[2])
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:170
Iterator End(void) const
Get an iterator which indicates past-the-last Node in the container.
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:223
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:441
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...
Network layer to device interface.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:322
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
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:552
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
holds a vector of ns3::NetDevice pointers
static void AsciiLrWpanMacTransmitSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p)
Output an ascii line representing the Transmit event (without context)
SET_PHY_TX_ON.
Definition: lr-wpan-mac.h:70
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.
static void AsciiLrWpanMacTransmitSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p)
Output an ascii line representing the Transmit event (with context)
static void DefaultDequeueSinkWithContext(Ptr< OutputStreamWrapper > file, std::string context, Ptr< const Packet > p)
Basic Dequeue default trace sink.
keep track of a set of node pointers.
prefix all trace prints with simulation time
Definition: log.h:96
LrWpanHelper(void)
Create a LrWpan helper in an empty state.
Iterator Begin(void) const
Get an iterator which refers to the first Node in the container.
prefix all trace prints with function
Definition: log.h:95
This class can contain 16 bit addresses.
Definition: mac16-address.h:39
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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:507
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:120
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Ptr< SingleModelSpectrumChannel > m_channel
channel to be used for the devices
MAC_IDLE.
Definition: lr-wpan-mac.h:64
void AddMobility(Ptr< LrWpanPhy > phy, Ptr< MobilityModel > m)
Add mobility model to a physical device.
tuple address
Definition: first.py:37
virtual ~LrWpanHelper(void)
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
void EnableLogComponents(void)
Helper to enable all LrWpan log components with one statement.
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:68
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.
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:94
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:485
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:318
Ptr< LrWpanMac > GetMac(void) const
Get the MAC used by this NetDevice.
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:69