A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lr-wpan-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 The Boeing Company
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 * Authors:
18 * Gary Pei <guangyu.pei@boeing.com>
19 * Tom Henderson <thomas.r.henderson@boeing.com>
20 */
21#include "lr-wpan-helper.h"
22
23#include "ns3/names.h"
24#include <ns3/log.h>
25#include <ns3/lr-wpan-csmaca.h>
26#include <ns3/lr-wpan-error-model.h>
27#include <ns3/lr-wpan-net-device.h>
28#include <ns3/mobility-model.h>
29#include <ns3/multi-model-spectrum-channel.h>
30#include <ns3/propagation-delay-model.h>
31#include <ns3/propagation-loss-model.h>
32#include <ns3/single-model-spectrum-channel.h>
33
34namespace ns3
35{
36
37NS_LOG_COMPONENT_DEFINE("LrWpanHelper");
38
39/**
40 * @brief Output an ascii line representing the Transmit event (with context)
41 * @param stream the output stream
42 * @param context the context
43 * @param p the packet
44 */
45static void
47 std::string context,
49{
50 *stream->GetStream() << "t " << Simulator::Now().As(Time::S) << " " << context << " " << *p
51 << std::endl;
52}
53
54/**
55 * @brief Output an ascii line representing the Transmit event (without context)
56 * @param stream the output stream
57 * @param p the packet
58 */
59static void
61{
62 *stream->GetStream() << "t " << Simulator::Now().As(Time::S) << " " << *p << std::endl;
63}
64
66{
67 m_channel = CreateObject<SingleModelSpectrumChannel>();
68
70 CreateObject<LogDistancePropagationLossModel>();
71 m_channel->AddPropagationLossModel(lossModel);
72
74 CreateObject<ConstantSpeedPropagationDelayModel>();
75 m_channel->SetPropagationDelayModel(delayModel);
76}
77
78LrWpanHelper::LrWpanHelper(bool useMultiModelSpectrumChannel)
79{
80 if (useMultiModelSpectrumChannel)
81 {
82 m_channel = CreateObject<MultiModelSpectrumChannel>();
83 }
84 else
85 {
86 m_channel = CreateObject<SingleModelSpectrumChannel>();
87 }
89 CreateObject<LogDistancePropagationLossModel>();
90 m_channel->AddPropagationLossModel(lossModel);
91
93 CreateObject<ConstantSpeedPropagationDelayModel>();
94 m_channel->SetPropagationDelayModel(delayModel);
95}
96
98{
99 m_channel->Dispose();
100 m_channel = nullptr;
101}
102
103void
105{
108 LogComponentEnable("LrWpanCsmaCa", LOG_LEVEL_ALL);
109 LogComponentEnable("LrWpanErrorModel", LOG_LEVEL_ALL);
110 LogComponentEnable("LrWpanInterferenceHelper", LOG_LEVEL_ALL);
111 LogComponentEnable("LrWpanMac", LOG_LEVEL_ALL);
112 LogComponentEnable("LrWpanNetDevice", LOG_LEVEL_ALL);
113 LogComponentEnable("LrWpanPhy", LOG_LEVEL_ALL);
114 LogComponentEnable("LrWpanSpectrumSignalParameters", LOG_LEVEL_ALL);
115 LogComponentEnable("LrWpanSpectrumValueHelper", LOG_LEVEL_ALL);
116}
117
118std::string
120{
121 switch (e)
122 {
124 return std::string("BUSY");
126 return std::string("BUSY_RX");
128 return std::string("BUSY_TX");
130 return std::string("FORCE_TRX_OFF");
132 return std::string("IDLE");
134 return std::string("INVALID_PARAMETER");
136 return std::string("RX_ON");
138 return std::string("SUCCESS");
140 return std::string("TRX_OFF");
142 return std::string("TX_ON");
144 return std::string("UNSUPPORTED_ATTRIBUTE");
146 return std::string("READ_ONLY");
148 return std::string("UNSPECIFIED");
149 default:
150 return std::string("INVALID");
151 }
152}
153
154std::string
156{
157 switch (e)
158 {
159 case lrwpan::MAC_IDLE:
160 return std::string("MAC_IDLE");
162 return std::string("CHANNEL_ACCESS_FAILURE");
164 return std::string("CHANNEL_IDLE");
166 return std::string("SET_PHY_TX_ON");
167 default:
168 return std::string("INVALID");
169 }
170}
171
172void
174{
175 phy->SetMobility(m);
176}
177
180{
181 NetDeviceContainer devices;
182 for (auto i = c.Begin(); i != c.End(); i++)
183 {
184 Ptr<Node> node = *i;
185
186 Ptr<lrwpan::LrWpanNetDevice> netDevice = CreateObject<lrwpan::LrWpanNetDevice>();
187 netDevice->SetChannel(m_channel);
188 node->AddDevice(netDevice);
189 netDevice->SetNode(node);
190 // \todo add the capability to change short address, extended
191 // address and panId. Right now they are hardcoded in LrWpanMac::LrWpanMac ()
192 devices.Add(netDevice);
193 }
194 return devices;
195}
196
199{
200 return m_channel;
201}
202
203void
205{
206 m_channel = channel;
207}
208
209void
210LrWpanHelper::SetChannel(std::string channelName)
211{
212 Ptr<SpectrumChannel> channel = Names::Find<SpectrumChannel>(channelName);
213 m_channel = channel;
214}
215
216int64_t
218{
219 int64_t currentStream = stream;
220 Ptr<NetDevice> netDevice;
221 for (auto i = c.Begin(); i != c.End(); ++i)
222 {
223 netDevice = (*i);
224 Ptr<lrwpan::LrWpanNetDevice> lrwpan = DynamicCast<lrwpan::LrWpanNetDevice>(netDevice);
225 if (lrwpan)
226 {
227 currentStream += lrwpan->AssignStreams(currentStream);
228 }
229 }
230 return (currentStream - stream);
231}
232
233void
235{
236 NetDeviceContainer devices;
237 uint16_t id = 1;
238 uint8_t idBuf[2] = {0, 0};
239 uint8_t idBuf2[8] = {0, 0, 0, 0, 0, 0, 0, 0};
240 Mac16Address address16;
241 Mac64Address address64;
242 Mac16Address coordShortAddr;
243 Mac64Address coordExtAddr;
244
245 for (auto i = c.Begin(); i != c.End(); i++)
246 {
247 if (id < 0x0001 || id > 0xFFFD)
248 {
249 NS_ABORT_MSG("Only 65533 addresses supported. Range [00:01]-[FF:FD]");
250 }
251
252 Ptr<lrwpan::LrWpanNetDevice> device = DynamicCast<lrwpan::LrWpanNetDevice>(*i);
253 if (device)
254 {
255 idBuf[0] = (id >> 8) & 0xff;
256 idBuf[1] = (id >> 0) & 0xff;
257 address16.CopyFrom(idBuf);
258
259 idBuf2[6] = (id >> 8) & 0xff;
260 idBuf2[7] = (id >> 0) & 0xff;
261 address64.CopyFrom(idBuf2);
262
263 if (address64 == Mac64Address("00:00:00:00:00:00:00:01"))
264 {
265 // We use the first device in the container as coordinator
266 coordShortAddr = address16;
267 coordExtAddr = address64;
268 }
269
270 // TODO: Change this to device->GetAddress() if GetAddress can guarantee a
271 // an extended address (currently only gives 48 address or 16 bits addresses)
272 device->GetMac()->SetExtendedAddress(address64);
273 device->SetPanAssociation(panId, coordExtAddr, coordShortAddr, address16);
274
275 id++;
276 }
277 }
278}
279
280void
282{
283 NetDeviceContainer devices;
284 uint64_t id = 1;
285 uint8_t idBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
286 Mac64Address address64;
287
288 for (auto i = c.Begin(); i != c.End(); i++)
289 {
290 Ptr<lrwpan::LrWpanNetDevice> device = DynamicCast<lrwpan::LrWpanNetDevice>(*i);
291 if (device)
292 {
293 idBuf[0] = (id >> 56) & 0xff;
294 idBuf[1] = (id >> 48) & 0xff;
295 idBuf[2] = (id >> 40) & 0xff;
296 idBuf[3] = (id >> 32) & 0xff;
297 idBuf[4] = (id >> 24) & 0xff;
298 idBuf[5] = (id >> 16) & 0xff;
299 idBuf[6] = (id >> 8) & 0xff;
300 idBuf[7] = (id >> 0) & 0xff;
301
302 address64.CopyFrom(idBuf);
303
304 // TODO: Change this to device->SetAddress() if GetAddress can guarantee
305 // to set only extended addresses
306 device->GetMac()->SetExtendedAddress(address64);
307
308 id++;
309 }
310 }
311}
312
313/**
314 * @brief Write a packet in a PCAP file
315 * @param file the output file
316 * @param packet the packet
317 */
318static void
320{
321 file->Write(Simulator::Now(), packet);
322}
323
324void
327 bool promiscuous,
328 bool explicitFilename)
329{
330 NS_LOG_FUNCTION(this << prefix << nd << promiscuous << explicitFilename);
331 //
332 // All of the Pcap enable functions vector through here including the ones
333 // that are wandering through all of devices on perhaps all of the nodes in
334 // the system.
335 //
336
337 // In the future, if we create different NetDevice types, we will
338 // have to switch on each type below and insert into the right
339 // NetDevice type
340 //
342 if (!device)
343 {
344 NS_LOG_INFO("LrWpanHelper::EnablePcapInternal(): Device "
345 << device << " not of type ns3::LrWpanNetDevice");
346 return;
347 }
348
349 PcapHelper pcapHelper;
350
351 std::string filename;
352 if (explicitFilename)
353 {
354 filename = prefix;
355 }
356 else
357 {
358 filename = pcapHelper.GetFilenameFromDevice(prefix, device);
359 }
360
362 pcapHelper.CreateFile(filename, std::ios::out, PcapHelper::DLT_IEEE802_15_4);
363
364 if (promiscuous)
365 {
366 device->GetMac()->TraceConnectWithoutContext("PromiscSniffer",
368 }
369 else
370 {
371 device->GetMac()->TraceConnectWithoutContext("Sniffer",
373 }
374}
375
376void
378 std::string prefix,
380 bool explicitFilename)
381{
382 uint32_t nodeid = nd->GetNode()->GetId();
383 uint32_t deviceid = nd->GetIfIndex();
384 std::ostringstream oss;
385
387 if (!device)
388 {
389 NS_LOG_INFO("LrWpanHelper::EnableAsciiInternal(): Device "
390 << device << " not of type ns3::LrWpanNetDevice");
391 return;
392 }
393
394 //
395 // Our default trace sinks are going to use packet printing, so we have to
396 // make sure that is turned on.
397 //
399
400 //
401 // If we are not provided an OutputStreamWrapper, we are expected to create
402 // one using the usual trace filename conventions and do a Hook*WithoutContext
403 // since there will be one file per context and therefore the context would
404 // be redundant.
405 //
406 if (!stream)
407 {
408 //
409 // Set up an output stream object to deal with private ofstream copy
410 // constructor and lifetime issues. Let the helper decide the actual
411 // name of the file given the prefix.
412 //
413 AsciiTraceHelper asciiTraceHelper;
414
415 std::string filename;
416 if (explicitFilename)
417 {
418 filename = prefix;
419 }
420 else
421 {
422 filename = asciiTraceHelper.GetFilenameFromDevice(prefix, device);
423 }
424
425 Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream(filename);
426
427 // Ascii traces typically have "+", '-", "d", "r", and sometimes "t"
428 // The Mac and Phy objects have the trace sources for these
429 //
430
431 asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
432 "MacRx",
433 theStream);
434
435 device->GetMac()->TraceConnectWithoutContext(
436 "MacTx",
438
439 asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
440 "MacTxEnqueue",
441 theStream);
442 asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
443 "MacTxDequeue",
444 theStream);
445 asciiTraceHelper.HookDefaultDropSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
446 "MacTxDrop",
447 theStream);
448
449 return;
450 }
451
452 //
453 // If we are provided an OutputStreamWrapper, we are expected to use it, and
454 // to provide a context. We are free to come up with our own context if we
455 // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
456 // compatibility and simplicity, we just use Config::Connect and let it deal
457 // with the context.
458 //
459 // Note that we are going to use the default trace sinks provided by the
460 // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
461 // but the default trace sinks are actually publicly available static
462 // functions that are always there waiting for just such a case.
463 //
464
465 oss.str("");
466 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
467 << "/$ns3::LrWpanNetDevice/Mac/MacRx";
468 device->GetMac()->TraceConnect(
469 "MacRx",
470 oss.str(),
472
473 oss.str("");
474 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
475 << "/$ns3::LrWpanNetDevice/Mac/MacTx";
476 device->GetMac()->TraceConnect(
477 "MacTx",
478 oss.str(),
480
481 oss.str("");
482 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
483 << "/$ns3::LrWpanNetDevice/Mac/MacTxEnqueue";
484 device->GetMac()->TraceConnect(
485 "MacTxEnqueue",
486 oss.str(),
488
489 oss.str("");
490 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
491 << "/$ns3::LrWpanNetDevice/Mac/MacTxDequeue";
492 device->GetMac()->TraceConnect(
493 "MacTxDequeue",
494 oss.str(),
496
497 oss.str("");
498 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
499 << "/$ns3::LrWpanNetDevice/Mac/MacTxDrop";
500 device->GetMac()->TraceConnect(
501 "MacTxDrop",
502 oss.str(),
504}
505
506} // 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.
Ptr< SpectrumChannel > GetChannel()
Get the channel associated to this helper.
Ptr< SpectrumChannel > m_channel
channel to be used for the devices
void SetChannel(Ptr< SpectrumChannel > channel)
Set the channel associated to this helper.
void AddMobility(Ptr< lrwpan::LrWpanPhy > phy, Ptr< MobilityModel > m)
Add mobility model to a physical device.
void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename) override
Enable pcap output on the indicated net device.
void CreateAssociatedPan(NetDeviceContainer c, uint16_t panId)
Creates an PAN with associated nodes and assigned addresses(16 and 64) from the nodes in the node con...
void SetExtendedAddresses(NetDeviceContainer c)
Set the extended 64 bit addresses (EUI-64) for a group of LrWpanNetDevices.
void EnableLogComponents()
Helper to enable all LrWpan log components with one statement.
static std::string LrWpanMacStatePrinter(lrwpan::MacState e)
Transform the LrWpanMacState enumeration into a printable string.
~LrWpanHelper() override
NetDeviceContainer Install(NodeContainer c)
Install a LrWpanNetDevice and the associated structures (e.g., channel) in the nodes.
void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename) override
Enable ascii trace output on the indicated net device.
static std::string LrWpanPhyEnumerationPrinter(lrwpan::PhyEnumeration e)
Transform the LrWpanPhyEnumeration enumeration into a printable string.
LrWpanHelper()
Create a LrWpan helper in an empty state.
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
void CopyFrom(const uint8_t buffer[2])
an EUI-64 address
Definition: mac64-address.h:46
void CopyFrom(const uint8_t buffer[8])
holds a vector of ns3::NetDevice pointers
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the 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.
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
Class that implements the LR-WPAN MAC state machine.
Definition: lr-wpan-mac.h:164
Network layer to device interface.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
MacState
MAC states.
Definition: lr-wpan-mac.h:75
PhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:115
@ CHANNEL_ACCESS_FAILURE
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:80
@ CHANNEL_IDLE
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:81
@ SET_PHY_TX_ON
SET_PHY_TX_ON.
Definition: lr-wpan-mac.h:82
@ MAC_IDLE
MAC_IDLE.
Definition: lr-wpan-mac.h:76
@ IEEE_802_15_4_PHY_BUSY
Definition: lr-wpan-phy.h:116
@ IEEE_802_15_4_PHY_READ_ONLY
Definition: lr-wpan-phy.h:127
@ IEEE_802_15_4_PHY_BUSY_TX
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:124
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:125
@ IEEE_802_15_4_PHY_INVALID_PARAMETER
Definition: lr-wpan-phy.h:121
@ IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE
Definition: lr-wpan-phy.h:126
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:123
@ IEEE_802_15_4_PHY_FORCE_TRX_OFF
Definition: lr-wpan-phy.h:119
@ IEEE_802_15_4_PHY_BUSY_RX
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_IDLE
Definition: lr-wpan-phy.h:120
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:128
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:767
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
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 AsciiLrWpanMacTransmitSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p)
Output an ascii line representing the Transmit event (without context)
static void PcapSniffLrWpan(Ptr< PcapFileWrapper > file, Ptr< const Packet > packet)
Write a packet in a PCAP file.
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition: log.h:119
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:320