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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors:
7 * Gary Pei <guangyu.pei@boeing.com>
8 * Tom Henderson <thomas.r.henderson@boeing.com>
9 */
10#include "lr-wpan-helper.h"
11
12#include "ns3/names.h"
13#include <ns3/log.h>
14#include <ns3/lr-wpan-csmaca.h>
15#include <ns3/lr-wpan-error-model.h>
16#include <ns3/lr-wpan-net-device.h>
17#include <ns3/mobility-model.h>
18#include <ns3/multi-model-spectrum-channel.h>
19#include <ns3/single-model-spectrum-channel.h>
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("LrWpanHelper");
25
26/**
27 * @brief Output an ascii line representing the Transmit event (with context)
28 * @param stream the output stream
29 * @param context the context
30 * @param p the packet
31 */
32static void
34 std::string context,
36{
37 *stream->GetStream() << "t " << Simulator::Now().As(Time::S) << " " << context << " " << *p
38 << std::endl;
39}
40
41/**
42 * @brief Output an ascii line representing the Transmit event (without context)
43 * @param stream the output stream
44 * @param p the packet
45 */
46static void
48{
49 *stream->GetStream() << "t " << Simulator::Now().As(Time::S) << " " << *p << std::endl;
50}
51
56
57LrWpanHelper::LrWpanHelper(bool useMultiModelSpectrumChannel)
58{
59 m_useMultiModelSpectrumChannel = useMultiModelSpectrumChannel;
60}
61
63{
64 m_channel->Dispose();
65 m_channel = nullptr;
66}
67
68void
70{
73 LogComponentEnable("LrWpanCsmaCa", LOG_LEVEL_ALL);
74 LogComponentEnable("LrWpanErrorModel", LOG_LEVEL_ALL);
75 LogComponentEnable("LrWpanInterferenceHelper", LOG_LEVEL_ALL);
77 LogComponentEnable("LrWpanNetDevice", LOG_LEVEL_ALL);
79 LogComponentEnable("LrWpanSpectrumSignalParameters", LOG_LEVEL_ALL);
80 LogComponentEnable("LrWpanSpectrumValueHelper", LOG_LEVEL_ALL);
81}
82
83std::string
85{
86 switch (e)
87 {
89 return std::string("BUSY");
91 return std::string("BUSY_RX");
93 return std::string("BUSY_TX");
95 return std::string("FORCE_TRX_OFF");
97 return std::string("IDLE");
99 return std::string("INVALID_PARAMETER");
101 return std::string("RX_ON");
103 return std::string("SUCCESS");
105 return std::string("TRX_OFF");
107 return std::string("TX_ON");
109 return std::string("UNSUPPORTED_ATTRIBUTE");
111 return std::string("READ_ONLY");
113 return std::string("UNSPECIFIED");
114 default:
115 return std::string("INVALID");
116 }
117}
118
119std::string
121{
122 switch (e)
123 {
124 case lrwpan::MAC_IDLE:
125 return std::string("MAC_IDLE");
127 return std::string("CHANNEL_ACCESS_FAILURE");
129 return std::string("CHANNEL_IDLE");
131 return std::string("SET_PHY_TX_ON");
132 default:
133 return std::string("INVALID");
134 }
135}
136
137void
139{
140 phy->SetMobility(m);
141}
142
145{
146 if (!m_channel)
147 {
149 {
151 }
152 else
153 {
155 }
157 {
158 SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel");
159 }
160 if (m_propagationLoss.empty())
161 {
162 AddPropagationLossModel("ns3::LogDistancePropagationLossModel");
163 }
164
165 for (auto i = m_propagationLoss.begin(); i != m_propagationLoss.end(); ++i)
166 {
168 m_channel->AddPropagationLossModel(cur);
169 }
171 m_channel->SetPropagationDelayModel(delay);
172 }
173 else
174 {
175 if (!m_channel->GetPropagationDelayModel())
176 {
177 NS_FATAL_ERROR("No propagation delay model added to the channel");
178 }
179 if (!m_channel->GetPropagationLossModel())
180 {
181 NS_FATAL_ERROR("No propagation loss model added to the channel");
182 }
183 }
184
185 NetDeviceContainer devices;
186 for (auto i = c.Begin(); i != c.End(); i++)
187 {
188 Ptr<Node> node = *i;
189
191 netDevice->SetChannel(m_channel);
192 node->AddDevice(netDevice);
193 netDevice->SetNode(node);
194 // \todo add the capability to change short address, extended
195 // address and panId. Right now they are hardcoded in LrWpanMac::LrWpanMac ()
196 devices.Add(netDevice);
197 }
198 return devices;
199}
200
203{
204 return m_channel;
205}
206
207void
212
213void
214LrWpanHelper::SetChannel(std::string channelName)
215{
217 m_channel = channel;
218}
219
220int64_t
222{
223 int64_t currentStream = stream;
224 Ptr<NetDevice> netDevice;
225 for (auto i = c.Begin(); i != c.End(); ++i)
226 {
227 netDevice = (*i);
229 if (lrwpan)
230 {
231 currentStream += lrwpan->AssignStreams(currentStream);
232 }
233 }
234 return (currentStream - stream);
235}
236
237void
239{
240 NetDeviceContainer devices;
241 uint16_t id = 1;
242 uint8_t idBuf[2] = {0, 0};
243 uint8_t idBuf2[8] = {0, 0, 0, 0, 0, 0, 0, 0};
244 Mac16Address address16;
245 Mac64Address address64;
246 Mac16Address coordShortAddr;
247 Mac64Address coordExtAddr;
248
249 for (auto i = c.Begin(); i != c.End(); i++)
250 {
251 if (id < 0x0001 || id > 0xFFFD)
252 {
253 NS_ABORT_MSG("Only 65533 addresses supported. Range [00:01]-[FF:FD]");
254 }
255
257 if (device)
258 {
259 idBuf[0] = (id >> 8) & 0xff;
260 idBuf[1] = (id >> 0) & 0xff;
261 address16.CopyFrom(idBuf);
262
263 idBuf2[6] = (id >> 8) & 0xff;
264 idBuf2[7] = (id >> 0) & 0xff;
265 address64.CopyFrom(idBuf2);
266
267 if (address64 == Mac64Address("00:00:00:00:00:00:00:01"))
268 {
269 // We use the first device in the container as coordinator
270 coordShortAddr = address16;
271 coordExtAddr = address64;
272 }
273
274 // TODO: Change this to device->GetAddress() if GetAddress can guarantee a
275 // an extended address (currently only gives 48 address or 16 bits addresses)
276 device->GetMac()->SetExtendedAddress(address64);
277 device->SetPanAssociation(panId, coordExtAddr, coordShortAddr, address16);
278
279 id++;
280 }
281 }
282}
283
284void
286{
287 NetDeviceContainer devices;
288 uint64_t id = 1;
289 uint8_t idBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
290 Mac64Address address64;
291
292 for (auto i = c.Begin(); i != c.End(); i++)
293 {
295 if (device)
296 {
297 idBuf[0] = (id >> 56) & 0xff;
298 idBuf[1] = (id >> 48) & 0xff;
299 idBuf[2] = (id >> 40) & 0xff;
300 idBuf[3] = (id >> 32) & 0xff;
301 idBuf[4] = (id >> 24) & 0xff;
302 idBuf[5] = (id >> 16) & 0xff;
303 idBuf[6] = (id >> 8) & 0xff;
304 idBuf[7] = (id >> 0) & 0xff;
305
306 address64.CopyFrom(idBuf);
307
308 // TODO: Change this to device->SetAddress() if GetAddress can guarantee
309 // to set only extended addresses
310 device->GetMac()->SetExtendedAddress(address64);
311
312 id++;
313 }
314 }
315}
316
317/**
318 * @brief Write a packet in a PCAP file
319 * @param file the output file
320 * @param packet the packet
321 */
322static void
324{
325 file->Write(Simulator::Now(), packet);
326}
327
328void
331 bool promiscuous,
332 bool explicitFilename)
333{
334 NS_LOG_FUNCTION(this << prefix << nd << promiscuous << explicitFilename);
335 //
336 // All of the Pcap enable functions vector through here including the ones
337 // that are wandering through all of devices on perhaps all of the nodes in
338 // the system.
339 //
340
341 // In the future, if we create different NetDevice types, we will
342 // have to switch on each type below and insert into the right
343 // NetDevice type
344 //
346 if (!device)
347 {
348 NS_LOG_INFO("LrWpanHelper::EnablePcapInternal(): Device "
349 << device << " not of type ns3::lrwpan::LrWpanNetDevice");
350 return;
351 }
352
353 PcapHelper pcapHelper;
354
355 std::string filename;
356 if (explicitFilename)
357 {
358 filename = prefix;
359 }
360 else
361 {
362 filename = pcapHelper.GetFilenameFromDevice(prefix, device);
363 }
364
366 pcapHelper.CreateFile(filename, std::ios::out, PcapHelper::DLT_IEEE802_15_4);
367
368 if (promiscuous)
369 {
370 device->GetMac()->TraceConnectWithoutContext("PromiscSniffer",
372 }
373 else
374 {
375 device->GetMac()->TraceConnectWithoutContext("Sniffer",
377 }
378}
379
380void
382 std::string prefix,
384 bool explicitFilename)
385{
386 uint32_t nodeid = nd->GetNode()->GetId();
387 uint32_t deviceid = nd->GetIfIndex();
388 std::ostringstream oss;
389
391 if (!device)
392 {
393 NS_LOG_INFO("LrWpanHelper::EnableAsciiInternal(): Device "
394 << device << " not of type ns3::LrWpanNetDevice");
395 return;
396 }
397
398 //
399 // Our default trace sinks are going to use packet printing, so we have to
400 // make sure that is turned on.
401 //
403
404 //
405 // If we are not provided an OutputStreamWrapper, we are expected to create
406 // one using the usual trace filename conventions and do a Hook*WithoutContext
407 // since there will be one file per context and therefore the context would
408 // be redundant.
409 //
410 if (!stream)
411 {
412 //
413 // Set up an output stream object to deal with private ofstream copy
414 // constructor and lifetime issues. Let the helper decide the actual
415 // name of the file given the prefix.
416 //
417 AsciiTraceHelper asciiTraceHelper;
418
419 std::string filename;
420 if (explicitFilename)
421 {
422 filename = prefix;
423 }
424 else
425 {
426 filename = asciiTraceHelper.GetFilenameFromDevice(prefix, device);
427 }
428
429 Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream(filename);
430
431 // Ascii traces typically have "+", '-", "d", "r", and sometimes "t"
432 // The Mac and Phy objects have the trace sources for these
433 //
434
435 asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
436 "MacRx",
437 theStream);
438
439 device->GetMac()->TraceConnectWithoutContext(
440 "MacTx",
442
443 asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
444 "MacTxEnqueue",
445 theStream);
446 asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
447 "MacTxDequeue",
448 theStream);
449 asciiTraceHelper.HookDefaultDropSinkWithoutContext<lrwpan::LrWpanMac>(device->GetMac(),
450 "MacTxDrop",
451 theStream);
452
453 return;
454 }
455
456 //
457 // If we are provided an OutputStreamWrapper, we are expected to use it, and
458 // to provide a context. We are free to come up with our own context if we
459 // want, and use the AsciiTraceHelper Hook*WithContext functions, but for
460 // compatibility and simplicity, we just use Config::Connect and let it deal
461 // with the context.
462 //
463 // Note that we are going to use the default trace sinks provided by the
464 // ascii trace helper. There is actually no AsciiTraceHelper in sight here,
465 // but the default trace sinks are actually publicly available static
466 // functions that are always there waiting for just such a case.
467 //
468
469 oss.str("");
470 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
471 << "/$ns3::lrwpan::LrWpanNetDevice/Mac/MacRx";
472 device->GetMac()->TraceConnect(
473 "MacRx",
474 oss.str(),
476
477 oss.str("");
478 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
479 << "/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTx";
480 device->GetMac()->TraceConnect(
481 "MacTx",
482 oss.str(),
484
485 oss.str("");
486 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
487 << "/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTxEnqueue";
488 device->GetMac()->TraceConnect(
489 "MacTxEnqueue",
490 oss.str(),
492
493 oss.str("");
494 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
495 << "/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTxDequeue";
496 device->GetMac()->TraceConnect(
497 "MacTxDequeue",
498 oss.str(),
500
501 oss.str("");
502 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid
503 << "/$ns3::lrwpan::LrWpanNetDevice/Mac/MacTxDrop";
504 device->GetMac()->TraceConnect(
505 "MacTxDrop",
506 oss.str(),
508}
509
510} // namespace ns3
Manage ASCII trace files for device models.
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...
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 ...
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 ...
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 ...
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...
std::vector< ObjectFactory > m_propagationLoss
vector of propagation loss models
bool m_useMultiModelSpectrumChannel
indicates whether a MultiModelSpectrumChannel is used
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.
ObjectFactory m_propagationDelay
propagation delay model
void SetPropagationDelayModel(std::string name, Ts &&... args)
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void AddPropagationLossModel(std::string name, Ts &&... args)
This class can contain 16 bit addresses.
void CopyFrom(const uint8_t buffer[2])
an EUI-64 address
void CopyFrom(const uint8_t buffer[8])
static Ptr< T > Find(std::string path)
Given a name path string, look to see if there's an object in the system with that associated to it.
Definition names.h:443
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.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
bool IsTypeIdSet() const
Check if the ObjectFactory has been configured with a TypeId.
static void EnablePrinting()
Enable printing packets metadata.
Definition packet.cc:585
Manage pcap files for device models.
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.
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.
calculate a propagation delay.
Models the propagation loss through a transmission medium.
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ S
second
Definition nstime.h:105
Class that implements the LR-WPAN MAC state machine.
Network layer to device interface.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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:264
MacState
MAC states.
Definition lr-wpan-mac.h:64
PhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
@ CHANNEL_ACCESS_FAILURE
CHANNEL_ACCESS_FAILURE.
Definition lr-wpan-mac.h:69
@ CHANNEL_IDLE
CHANNEL_IDLE.
Definition lr-wpan-mac.h:70
@ SET_PHY_TX_ON
SET_PHY_TX_ON.
Definition lr-wpan-mac.h:71
@ MAC_IDLE
MAC_IDLE.
Definition lr-wpan-mac.h:65
@ IEEE_802_15_4_PHY_BUSY
@ IEEE_802_15_4_PHY_READ_ONLY
@ IEEE_802_15_4_PHY_BUSY_TX
@ IEEE_802_15_4_PHY_RX_ON
@ IEEE_802_15_4_PHY_TRX_OFF
@ IEEE_802_15_4_PHY_TX_ON
@ IEEE_802_15_4_PHY_INVALID_PARAMETER
@ IEEE_802_15_4_PHY_UNSUPPORTED_ATTRIBUTE
@ IEEE_802_15_4_PHY_SUCCESS
@ IEEE_802_15_4_PHY_FORCE_TRX_OFF
@ IEEE_802_15_4_PHY_BUSY_RX
@ IEEE_802_15_4_PHY_IDLE
@ IEEE_802_15_4_PHY_UNSPECIFIED
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
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:291
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)
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
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:105
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition log.h:107
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:108
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:309