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 
35 static void
38  std::string context,
40 {
41  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << context << " " << *p << std::endl;
42 }
43 
44 static void
48 {
49  *stream->GetStream () << "t " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
50 }
51 
53 {
54  m_channel = CreateObject<SingleModelSpectrumChannel> ();
55  Ptr<LogDistancePropagationLossModel> model = CreateObject<LogDistancePropagationLossModel> ();
56  m_channel->AddPropagationLossModel (model);
57 }
58 
60 {
61  m_channel->Dispose ();
62  m_channel = 0;
63 }
64 
65 void
67 {
70  LogComponentEnable ("LrWpanCsmaCa", LOG_LEVEL_ALL);
71  LogComponentEnable ("LrWpanErrorModel", LOG_LEVEL_ALL);
72  LogComponentEnable ("LrWpanInterferenceHelper", LOG_LEVEL_ALL);
73  LogComponentEnable ("LrWpanMac", LOG_LEVEL_ALL);
74  LogComponentEnable ("LrWpanNetDevice", LOG_LEVEL_ALL);
75  LogComponentEnable ("LrWpanPhy", LOG_LEVEL_ALL);
76  LogComponentEnable ("LrWpanSpectrumSignalParameters", LOG_LEVEL_ALL);
77  LogComponentEnable ("LrWpanSpectrumValueHelper", LOG_LEVEL_ALL);
78 }
79 
80 std::string
82 {
83  switch (e)
84  {
86  return std::string ("BUSY");
88  return std::string ("BUSY_RX");
90  return std::string ("BUSY_TX");
92  return std::string ("FORCE_TRX_OFF");
94  return std::string ("IDLE");
96  return std::string ("INVALID_PARAMETER");
98  return std::string ("RX_ON");
100  return std::string ("SUCCESS");
102  return std::string ("TRX_OFF");
104  return std::string ("TX_ON");
106  return std::string ("UNSUPPORTED_ATTRIBUTE");
108  return std::string ("READ_ONLY");
110  return std::string ("UNSPECIFIED");
111  default:
112  return std::string ("INVALID");
113  }
114 }
115 
116 std::string
118 {
119  switch (e)
120  {
121  case MAC_IDLE:
122  return std::string ("MAC_IDLE");
124  return std::string ("CHANNEL_ACCESS_FAILURE");
125  case CHANNEL_IDLE:
126  return std::string ("CHANNEL_IDLE");
127  case SET_PHY_TX_ON:
128  return std::string ("SET_PHY_TX_ON");
129  default:
130  return std::string ("INVALID");
131  }
132 }
133 
134 void
136 {
137  phy->SetMobility (m);
138 }
139 
142 {
144  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
145  {
146  Ptr<Node> node = *i;
147 
148  Ptr<LrWpanNetDevice> netDevice = CreateObject<LrWpanNetDevice> ();
149  netDevice->SetChannel (m_channel);
150  node->AddDevice (netDevice);
151  netDevice->SetNode (node);
152  // \todo add the capability to change short address, extended
153  // address and panId. Right now they are hardcoded in LrWpanMac::LrWpanMac ()
154  devices.Add (netDevice);
155  }
156  return devices;
157 }
158 
159 int64_t
161 {
162  int64_t currentStream = stream;
163  Ptr<NetDevice> netDevice;
164  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
165  {
166  netDevice = (*i);
167  Ptr<LrWpanNetDevice> lrwpan = DynamicCast<LrWpanNetDevice> (netDevice);
168  if (lrwpan)
169  {
170  currentStream += lrwpan->AssignStreams (currentStream);
171  }
172  }
173  return (currentStream - stream);
174 }
175 
176 void
178 {
180  uint16_t id = 1;
181  uint8_t idBuf[2];
182 
183  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); i++)
184  {
185  Ptr<LrWpanNetDevice> device = DynamicCast<LrWpanNetDevice> (*i);
186  if (device)
187  {
188  idBuf[0] = (id >> 8) & 0xff;
189  idBuf[1] = (id >> 0) & 0xff;
191  address.CopyFrom (idBuf);
192 
193  device->GetMac ()->SetPanId (panId);
194  device->GetMac ()->SetShortAddress (address);
195  id++;
196  }
197  }
198  return;
199 }
200 
201 static void
203 {
204  file->Write (Simulator::Now (), packet);
205 }
206 
207 void
208 LrWpanHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
209 {
210  NS_LOG_FUNCTION (this << prefix << nd << promiscuous << explicitFilename);
211  //
212  // All of the Pcap enable functions vector through here including the ones
213  // that are wandering through all of devices on perhaps all of the nodes in
214  // the system.
215  //
216 
217  // In the future, if we create different NetDevice types, we will
218  // have to switch on each type below and insert into the right
219  // NetDevice type
220  //
221  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
222  if (device == 0)
223  {
224  NS_LOG_INFO ("LrWpanHelper::EnablePcapInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
225  return;
226  }
227 
228  PcapHelper pcapHelper;
229 
230  std::string filename;
231  if (explicitFilename)
232  {
233  filename = prefix;
234  }
235  else
236  {
237  filename = pcapHelper.GetFilenameFromDevice (prefix, device);
238  }
239 
240  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
242 
243  if (promiscuous == true)
244  {
245  device->GetMac ()->TraceConnectWithoutContext ("PromiscSniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
246 
247  }
248  else
249  {
250  device->GetMac ()->TraceConnectWithoutContext ("Sniffer", MakeBoundCallback (&PcapSniffLrWpan, file));
251  }
252 }
253 
254 void
257  std::string prefix,
258  Ptr<NetDevice> nd,
259  bool explicitFilename)
260 {
261  uint32_t nodeid = nd->GetNode ()->GetId ();
262  uint32_t deviceid = nd->GetIfIndex ();
263  std::ostringstream oss;
264 
265  Ptr<LrWpanNetDevice> device = nd->GetObject<LrWpanNetDevice> ();
266  if (device == 0)
267  {
268  NS_LOG_INFO ("LrWpanHelper::EnableAsciiInternal(): Device " << device << " not of type ns3::LrWpanNetDevice");
269  return;
270  }
271 
272  //
273  // Our default trace sinks are going to use packet printing, so we have to
274  // make sure that is turned on.
275  //
277 
278  //
279  // If we are not provided an OutputStreamWrapper, we are expected to create
280  // one using the usual trace filename conventions and do a Hook*WithoutContext
281  // since there will be one file per context and therefore the context would
282  // be redundant.
283  //
284  if (stream == 0)
285  {
286  //
287  // Set up an output stream object to deal with private ofstream copy
288  // constructor and lifetime issues. Let the helper decide the actual
289  // name of the file given the prefix.
290  //
291  AsciiTraceHelper asciiTraceHelper;
292 
293  std::string filename;
294  if (explicitFilename)
295  {
296  filename = prefix;
297  }
298  else
299  {
300  filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
301  }
302 
303  Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
304 
305  // Ascii traces typically have "+", '-", "d", "r", and sometimes "t"
306  // The Mac and Phy objects have the trace sources for these
307  //
308 
309  asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<LrWpanNetDevice> (device, "MacRx", theStream);
310 
311  device->GetMac ()->TraceConnectWithoutContext ("MacTx", MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithoutContext, theStream));
312 
313  asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<LrWpanNetDevice> (device, "MacTxEnqueue", theStream);
314  asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<LrWpanNetDevice> (device, "MacTxDequeue", theStream);
315  asciiTraceHelper.HookDefaultDropSinkWithoutContext<LrWpanNetDevice> (device, "MacTxDrop", theStream);
316 
317  return;
318  }
319 
320  //
321  // If we are provided an OutputStreamWrapper, we are expected to use it, and
322  // to provide a context. We are free to come up with our own context if we
323  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
324  // compatibility and simplicity, we just use Config::Connect and let it deal
325  // with the context.
326  //
327  // Note that we are going to use the default trace sinks provided by the
328  // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
329  // but the default trace sinks are actually publicly available static
330  // functions that are always there waiting for just such a case.
331  //
332 
333 
334  oss.str ("");
335  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacRx";
336  device->GetMac ()->TraceConnect ("MacRx", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultReceiveSinkWithContext, stream));
337 
338  oss.str ("");
339  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTx";
340  device->GetMac ()->TraceConnect ("MacTx", oss.str (), MakeBoundCallback (&AsciiLrWpanMacTransmitSinkWithContext, stream));
341 
342  oss.str ("");
343  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxEnqueue";
344  device->GetMac ()->TraceConnect ("MacTxEnqueue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqueueSinkWithContext, stream));
345 
346  oss.str ("");
347  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDequeue";
348  device->GetMac ()->TraceConnect ("MacTxDequeue", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequeueSinkWithContext, stream));
349 
350  oss.str ("");
351  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::LrWpanNetDevice/Mac/MacTxDrop";
352  device->GetMac ()->TraceConnect ("MacTxDrop", oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
353 
354 }
355 
356 } // namespace ns3
357 
void LogComponentEnableAll(enum LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:342
NetDeviceContainer Install(NodeContainer c)
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
LrWpanMacState
Definition: lr-wpan-mac.h:55
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
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)
Build bound Callbacks which take varying numbers of arguments, and potentially returning a value...
Definition: callback.h:1467
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)
#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
Definition: nstime.h:272
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)
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)
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)
Definition: node.cc:120
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Ptr< SingleModelSpectrumChannel > m_channel
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.
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)
static std::string LrWpanPhyEnumerationPrinter(LrWpanPhyEnumeration)
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:93
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.