A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lorawan-mac-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 */
8
10
11#include "ns3/end-device-lora-phy.h"
12#include "ns3/gateway-lora-phy.h"
13#include "ns3/log.h"
14#include "ns3/lora-net-device.h"
15#include "ns3/random-variable-stream.h"
16
17namespace ns3
18{
19namespace lorawan
20{
21
22NS_LOG_COMPONENT_DEFINE("LorawanMacHelper");
23
28
29void
30LorawanMacHelper::Set(std::string name, const AttributeValue& v)
31{
32 m_mac.Set(name, v);
33}
34
35void
37{
38 NS_LOG_FUNCTION(this << dt);
39 switch (dt)
40 {
41 case GW:
42 m_mac.SetTypeId("ns3::GatewayLorawanMac");
43 break;
44 case ED_A:
45 m_mac.SetTypeId("ns3::ClassAEndDeviceLorawanMac");
46 break;
47 }
48 m_deviceType = dt;
49}
50
51void
58
59void
64
67{
69 mac->SetDevice(device);
70
71 // If we are operating on an end device, add an address to it
72 if (m_deviceType == ED_A && m_addrGen)
73 {
74 DynamicCast<ClassAEndDeviceLorawanMac>(mac)->SetDeviceAddress(m_addrGen->NextAddress());
75 }
76
77 // Add a basic list of channels based on the region where the device is
78 // operating
79 if (m_deviceType == ED_A)
80 {
82 switch (m_region)
83 {
86 break;
87 }
90 break;
91 }
94 break;
95 }
96 default: {
97 NS_LOG_ERROR("This region isn't supported yet!");
98 break;
99 }
100 }
101 }
102 else
103 {
105 switch (m_region)
106 {
109 break;
110 }
113 break;
114 }
117 break;
118 }
119 default: {
120 NS_LOG_ERROR("This region isn't supported yet!");
121 break;
122 }
123 }
124 }
125 return mac;
126}
127
128void
130{
132
134
135 /////////////////////////////////////////////////////////
136 // TxPower -> Transmission power in dBm ERP conversion //
137 /////////////////////////////////////////////////////////
138 edMac->SetTxDbmForTxPower(std::vector<double>{14, 12, 10, 8, 6, 4, 2, 0});
139
140 ////////////////////////////////////////////////////////////
141 // Matrix to know which data rate the gateway will respond with //
142 ////////////////////////////////////////////////////////////
143 LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}},
144 {{1, 0, 0, 0, 0, 0}},
145 {{2, 1, 0, 0, 0, 0}},
146 {{3, 2, 1, 0, 0, 0}},
147 {{4, 3, 2, 1, 0, 0}},
148 {{5, 4, 3, 2, 1, 0}},
149 {{6, 5, 4, 3, 2, 1}},
150 {{7, 6, 5, 4, 3, 2}}}};
151 edMac->SetReplyDataRateMatrix(matrix);
152
153 /////////////////////
154 // Preamble length //
155 /////////////////////
156 edMac->SetNPreambleSymbols(8);
157
158 //////////////////////////////////////
159 // Second receive window parameters //
160 //////////////////////////////////////
161 edMac->SetSecondReceiveWindowDataRate(0);
162 edMac->SetSecondReceiveWindowFrequency(869525000);
163}
164
165void
167{
169
170 ///////////////////////////////
171 // ReceivePath configuration //
172 ///////////////////////////////
173 Ptr<GatewayLoraPhy> gwPhy =
174 DynamicCast<GatewayLoraPhy>(DynamicCast<LoraNetDevice>(gwMac->GetDevice())->GetPhy());
175
177
178 if (gwPhy) // If cast is successful, there's a GatewayLoraPhy
179 {
180 NS_LOG_DEBUG("Resetting reception paths");
181 gwPhy->ResetReceptionPaths();
182
183 int receptionPaths = 0;
184 int maxReceptionPaths = 1;
185 while (receptionPaths < maxReceptionPaths)
186 {
187 DynamicCast<GatewayLoraPhy>(gwPhy)->AddReceptionPath();
188 receptionPaths++;
189 }
190 gwPhy->AddFrequency(868100000);
191 }
192}
193
194void
196{
198
199 //////////////
200 // SubBands //
201 //////////////
202
203 auto channelHelper = Create<LogicalLoraChannelHelper>(1);
204 channelHelper->AddSubBand(Create<SubBand>(868000000, 868600000, 1, 14));
205
206 //////////////////////
207 // Default channels //
208 //////////////////////
210 channelHelper->SetChannel(0, lc1);
211
212 lorawanMac->SetLogicalLoraChannelHelper(channelHelper);
213
214 ///////////////////////////////////////////////////////////
215 // Data rate -> Spreading factor, Data rate -> Bandwidth //
216 // and Data rate -> MaxAppPayload conversions //
217 ///////////////////////////////////////////////////////////
218 lorawanMac->SetSfForDataRate(std::vector<uint8_t>{12, 11, 10, 9, 8, 7, 7});
219 lorawanMac->SetBandwidthForDataRate(
220 std::vector<double>{125000, 125000, 125000, 125000, 125000, 125000, 250000});
221 lorawanMac->SetMaxAppPayloadForDataRate(
222 std::vector<uint32_t>{59, 59, 59, 123, 230, 230, 230, 230});
223}
224
225void
227{
229
231
232 /////////////////////////////////////////////////////////
233 // TxPower -> Transmission power in dBm ERP conversion //
234 /////////////////////////////////////////////////////////
235 edMac->SetTxDbmForTxPower(std::vector<double>{14, 12, 10, 8, 6, 4, 2, 0});
236
237 ////////////////////////////////////////////////////////////
238 // Matrix to know which data rate the gateway will respond with //
239 ////////////////////////////////////////////////////////////
240 LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}},
241 {{1, 0, 0, 0, 0, 0}},
242 {{2, 1, 0, 0, 0, 0}},
243 {{3, 2, 1, 0, 0, 0}},
244 {{4, 3, 2, 1, 0, 0}},
245 {{5, 4, 3, 2, 1, 0}},
246 {{6, 5, 4, 3, 2, 1}},
247 {{7, 6, 5, 4, 3, 2}}}};
248 edMac->SetReplyDataRateMatrix(matrix);
249
250 /////////////////////
251 // Preamble length //
252 /////////////////////
253 edMac->SetNPreambleSymbols(8);
254
255 //////////////////////////////////////
256 // Second receive window parameters //
257 //////////////////////////////////////
258 edMac->SetSecondReceiveWindowDataRate(0);
259 edMac->SetSecondReceiveWindowFrequency(869525000);
260}
261
262void
264{
266
267 ///////////////////////////////
268 // ReceivePath configuration //
269 ///////////////////////////////
270 Ptr<GatewayLoraPhy> gwPhy =
271 DynamicCast<GatewayLoraPhy>(DynamicCast<LoraNetDevice>(gwMac->GetDevice())->GetPhy());
272
274
275 if (gwPhy) // If cast is successful, there's a GatewayLoraPhy
276 {
277 NS_LOG_DEBUG("Resetting reception paths");
278 gwPhy->ResetReceptionPaths();
279
280 std::vector<uint32_t> frequencies;
281 frequencies.push_back(868100000);
282 frequencies.push_back(868300000);
283 frequencies.push_back(868500000);
284
285 for (auto& f : frequencies)
286 {
287 gwPhy->AddFrequency(f);
288 }
289
290 int receptionPaths = 0;
291 int maxReceptionPaths = 8;
292 while (receptionPaths < maxReceptionPaths)
293 {
294 DynamicCast<GatewayLoraPhy>(gwPhy)->AddReceptionPath();
295 receptionPaths++;
296 }
297 }
298}
299
300void
302{
304
305 //////////////
306 // SubBands //
307 //////////////
308
309 auto channelHelper = Create<LogicalLoraChannelHelper>(16);
310 channelHelper->AddSubBand(Create<SubBand>(863000000, 865000000, 0.001, 14));
311 channelHelper->AddSubBand(Create<SubBand>(865000000, 868000000, 0.01, 14));
312 channelHelper->AddSubBand(Create<SubBand>(868000000, 868600000, 0.01, 14));
313 channelHelper->AddSubBand(Create<SubBand>(868700000, 869200000, 0.001, 14));
314 channelHelper->AddSubBand(Create<SubBand>(869400000, 869650000, 0.1, 27));
315 channelHelper->AddSubBand(Create<SubBand>(869700000, 870000000, 0.01, 14));
316
317 //////////////////////
318 // Default channels //
319 //////////////////////
323 channelHelper->SetChannel(0, lc1);
324 channelHelper->SetChannel(1, lc2);
325 channelHelper->SetChannel(2, lc3);
326
327 lorawanMac->SetLogicalLoraChannelHelper(channelHelper);
328
329 ///////////////////////////////////////////////////////////
330 // Data rate -> Spreading factor, Data rate -> Bandwidth //
331 // and Data rate -> MaxAppPayload conversions //
332 ///////////////////////////////////////////////////////////
333 lorawanMac->SetSfForDataRate(std::vector<uint8_t>{12, 11, 10, 9, 8, 7, 7});
334 lorawanMac->SetBandwidthForDataRate(
335 std::vector<double>{125000, 125000, 125000, 125000, 125000, 125000, 250000});
336 lorawanMac->SetMaxAppPayloadForDataRate(
337 std::vector<uint32_t>{59, 59, 59, 123, 230, 230, 230, 230});
338}
339
340///////////////////////////////
341
342void
344{
346
348
349 /////////////////////////////////////////////////////////
350 // TxPower -> Transmission power in dBm ERP conversion //
351 /////////////////////////////////////////////////////////
352 edMac->SetTxDbmForTxPower(std::vector<double>{14, 12, 10, 8, 6, 4, 2, 0});
353
354 ////////////////////////////////////////////////////////////
355 // Matrix to know which DataRate the gateway will respond with //
356 ////////////////////////////////////////////////////////////
357 LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}},
358 {{1, 0, 0, 0, 0, 0}},
359 {{2, 1, 0, 0, 0, 0}},
360 {{3, 2, 1, 0, 0, 0}},
361 {{4, 3, 2, 1, 0, 0}},
362 {{5, 4, 3, 2, 1, 0}},
363 {{6, 5, 4, 3, 2, 1}},
364 {{7, 6, 5, 4, 3, 2}}}};
365 edMac->SetReplyDataRateMatrix(matrix);
366
367 /////////////////////
368 // Preamble length //
369 /////////////////////
370 edMac->SetNPreambleSymbols(8);
371
372 //////////////////////////////////////
373 // Second receive window parameters //
374 //////////////////////////////////////
375 edMac->SetSecondReceiveWindowDataRate(0);
376 edMac->SetSecondReceiveWindowFrequency(869525000);
377}
378
379void
381{
383
384 ///////////////////////////////
385 // ReceivePath configuration //
386 ///////////////////////////////
387 Ptr<GatewayLoraPhy> gwPhy =
388 DynamicCast<GatewayLoraPhy>(DynamicCast<LoraNetDevice>(gwMac->GetDevice())->GetPhy());
389
391
392 if (gwPhy) // If cast is successful, there's a GatewayLoraPhy
393 {
394 NS_LOG_DEBUG("Resetting reception paths");
395 gwPhy->ResetReceptionPaths();
396
397 std::vector<uint32_t> frequencies;
398 frequencies.push_back(868100000);
399
400 for (auto& f : frequencies)
401 {
402 gwPhy->AddFrequency(f);
403 }
404
405 int receptionPaths = 0;
406 int maxReceptionPaths = 8;
407 while (receptionPaths < maxReceptionPaths)
408 {
409 gwPhy->AddReceptionPath();
410 receptionPaths++;
411 }
412 }
413}
414
415void
417{
419
420 //////////////
421 // SubBands //
422 //////////////
423
424 auto channelHelper = Create<LogicalLoraChannelHelper>(1);
425 channelHelper->AddSubBand(Create<SubBand>(868000000, 868600000, 0.01, 14));
426
427 //////////////////////
428 // Default channels //
429 //////////////////////
431 channelHelper->SetChannel(0, lc1);
432
433 lorawanMac->SetLogicalLoraChannelHelper(channelHelper);
434
435 ///////////////////////////////////////////////////////////
436 // Data rate -> Spreading factor, Data rate -> Bandwidth //
437 // and Data rate -> MaxAppPayload conversions //
438 ///////////////////////////////////////////////////////////
439 lorawanMac->SetSfForDataRate(std::vector<uint8_t>{12, 11, 10, 9, 8, 7, 7});
440 lorawanMac->SetBandwidthForDataRate(
441 std::vector<double>{125000, 125000, 125000, 125000, 125000, 125000, 250000});
442 lorawanMac->SetMaxAppPayloadForDataRate(
443 std::vector<uint32_t>{59, 59, 59, 123, 230, 230, 230, 230});
444}
445
446std::vector<int>
448 NodeContainer gateways,
449 Ptr<LoraChannel> channel)
450{
452
453 std::vector<int> sfQuantity(7, 0);
454 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
455 {
456 Ptr<Node> object = *j;
457 Ptr<MobilityModel> position = object->GetObject<MobilityModel>();
458 NS_ASSERT(position);
459 Ptr<NetDevice> netDevice = object->GetDevice(0);
460 Ptr<LoraNetDevice> loraNetDevice = DynamicCast<LoraNetDevice>(netDevice);
461 NS_ASSERT(loraNetDevice);
463 DynamicCast<ClassAEndDeviceLorawanMac>(loraNetDevice->GetMac());
464 NS_ASSERT(mac);
465
466 // Try computing the distance from each gateway and find the best one
467 Ptr<Node> bestGateway = gateways.Get(0);
468 Ptr<MobilityModel> bestGatewayPosition = bestGateway->GetObject<MobilityModel>();
469
470 // Assume devices transmit at 14 dBm
471 double highestRxPower = channel->GetRxPower(14, position, bestGatewayPosition);
472
473 for (auto currentGw = gateways.Begin() + 1; currentGw != gateways.End(); ++currentGw)
474 {
475 // Compute the power received from the current gateway
476 Ptr<Node> curr = *currentGw;
477 Ptr<MobilityModel> currPosition = curr->GetObject<MobilityModel>();
478 double currentRxPower = channel->GetRxPower(14, position, currPosition); // dBm
479
480 if (currentRxPower > highestRxPower)
481 {
482 bestGateway = curr;
483 bestGatewayPosition = currPosition;
484 highestRxPower = currentRxPower;
485 }
486 }
487
488 // NS_LOG_DEBUG ("Rx Power: " << highestRxPower);
489 double rxPower = highestRxPower;
490
491 // Get the end device sensitivity
492 Ptr<EndDeviceLoraPhy> edPhy = DynamicCast<EndDeviceLoraPhy>(loraNetDevice->GetPhy());
493 const double* edSensitivity = EndDeviceLoraPhy::sensitivity;
494
495 if (rxPower > *edSensitivity)
496 {
497 mac->SetDataRate(5);
498 sfQuantity[0] = sfQuantity[0] + 1;
499 }
500 else if (rxPower > *(edSensitivity + 1))
501 {
502 mac->SetDataRate(4);
503 sfQuantity[1] = sfQuantity[1] + 1;
504 }
505 else if (rxPower > *(edSensitivity + 2))
506 {
507 mac->SetDataRate(3);
508 sfQuantity[2] = sfQuantity[2] + 1;
509 }
510 else if (rxPower > *(edSensitivity + 3))
511 {
512 mac->SetDataRate(2);
513 sfQuantity[3] = sfQuantity[3] + 1;
514 }
515 else if (rxPower > *(edSensitivity + 4))
516 {
517 mac->SetDataRate(1);
518 sfQuantity[4] = sfQuantity[4] + 1;
519 }
520 else if (rxPower > *(edSensitivity + 5))
521 {
522 mac->SetDataRate(0);
523 sfQuantity[5] = sfQuantity[5] + 1;
524 }
525 else // Device is out of range. Assign SF12.
526 {
527 // NS_LOG_DEBUG ("Device out of range");
528 mac->SetDataRate(0);
529 sfQuantity[6] = sfQuantity[6] + 1;
530 // NS_LOG_DEBUG ("sfQuantity[6] = " << sfQuantity[6]);
531 }
532
533 /*
534
535 // Get the Gw sensitivity
536 Ptr<NetDevice> gatewayNetDevice = bestGateway->GetDevice (0);
537 Ptr<LoraNetDevice> gatewayLoraNetDevice = DynamicCast<LoraNetDevice>(gatewayNetDevice);
538 Ptr<GatewayLoraPhy> gatewayPhy = DynamicCast<GatewayLoraPhy>
539 (gatewayLoraNetDevice->GetPhy ()); const double *gwSensitivity = gatewayPhy->sensitivity;
540
541 if(rxPower > *gwSensitivity)
542 {
543 mac->SetDataRate (5);
544 sfQuantity[0] = sfQuantity[0] + 1;
545
546 }
547 else if (rxPower > *(gwSensitivity+1))
548 {
549 mac->SetDataRate (4);
550 sfQuantity[1] = sfQuantity[1] + 1;
551
552 }
553 else if (rxPower > *(gwSensitivity+2))
554 {
555 mac->SetDataRate (3);
556 sfQuantity[2] = sfQuantity[2] + 1;
557
558 }
559 else if (rxPower > *(gwSensitivity+3))
560 {
561 mac->SetDataRate (2);
562 sfQuantity[3] = sfQuantity[3] + 1;
563 }
564 else if (rxPower > *(gwSensitivity+4))
565 {
566 mac->SetDataRate (1);
567 sfQuantity[4] = sfQuantity[4] + 1;
568 }
569 else if (rxPower > *(gwSensitivity+5))
570 {
571 mac->SetDataRate (0);
572 sfQuantity[5] = sfQuantity[5] + 1;
573
574 }
575 else // Device is out of range. Assign SF12.
576 {
577 mac->SetDataRate (0);
578 sfQuantity[6] = sfQuantity[6] + 1;
579
580 }
581 */
582
583 } // end loop on nodes
584
585 return sfQuantity;
586
587} // end function
588
589std::vector<int>
591 NodeContainer gateways,
592 std::vector<double> distribution)
593{
595 NS_ASSERT(distribution.size() == 6);
596
597 std::vector<int> sfQuantity(7, 0);
599 std::vector<double> cumdistr(6);
600 cumdistr[0] = distribution[0];
601 for (int i = 1; i < 6; ++i)
602 {
603 cumdistr[i] = distribution[i] + cumdistr[i - 1];
604 }
605
606 NS_LOG_DEBUG("Distribution: " << distribution[0] << " " << distribution[1] << " "
607 << distribution[2] << " " << distribution[3] << " "
608 << distribution[4] << " " << distribution[5]);
609 NS_LOG_DEBUG("Cumulative distribution: " << cumdistr[0] << " " << cumdistr[1] << " "
610 << cumdistr[2] << " " << cumdistr[3] << " "
611 << cumdistr[4] << " " << cumdistr[5]);
612
613 for (auto j = endDevices.Begin(); j != endDevices.End(); ++j)
614 {
615 Ptr<Node> object = *j;
616 Ptr<MobilityModel> position = object->GetObject<MobilityModel>();
617 NS_ASSERT(position);
618 Ptr<NetDevice> netDevice = object->GetDevice(0);
619 Ptr<LoraNetDevice> loraNetDevice = DynamicCast<LoraNetDevice>(netDevice);
620 NS_ASSERT(loraNetDevice);
622 DynamicCast<ClassAEndDeviceLorawanMac>(loraNetDevice->GetMac());
623 NS_ASSERT(mac);
624
625 double prob = uniformRV->GetValue(0, 1);
626
627 // NS_LOG_DEBUG ("Probability: " << prob);
628 if (prob < cumdistr[0])
629 {
630 mac->SetDataRate(5);
631 sfQuantity[0] = sfQuantity[0] + 1;
632 }
633 else if (prob > cumdistr[0] && prob < cumdistr[1])
634 {
635 mac->SetDataRate(4);
636 sfQuantity[1] = sfQuantity[1] + 1;
637 }
638 else if (prob > cumdistr[1] && prob < cumdistr[2])
639 {
640 mac->SetDataRate(3);
641 sfQuantity[2] = sfQuantity[2] + 1;
642 }
643 else if (prob > cumdistr[2] && prob < cumdistr[3])
644 {
645 mac->SetDataRate(2);
646 sfQuantity[3] = sfQuantity[3] + 1;
647 }
648 else if (prob > cumdistr[3] && prob < cumdistr[4])
649 {
650 mac->SetDataRate(1);
651 sfQuantity[4] = sfQuantity[4] + 1;
652 }
653 else
654 {
655 mac->SetDataRate(0);
656 sfQuantity[5] = sfQuantity[5] + 1;
657 }
658
659 } // end loop on nodes
660
661 return sfQuantity;
662
663} // end function
664
665} // namespace lorawan
666} // namespace ns3
Hold a value for an Attribute.
Definition attribute.h:59
Keep track of the current position and velocity of an object.
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< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Smart pointer class similar to boost::intrusive_ptr.
static const double sensitivity[6]
The sensitivity vector of this device to different SFs.
Helper class for configuring and installing the LorawanMac class on devices and gateways.
void ConfigureForAlohaRegion(Ptr< ClassAEndDeviceLorawanMac > edMac) const
Perform region-specific configurations for the ALOHA band.
LorawanMacHelper()
Default constructor.
void SetDeviceType(enum DeviceType dt)
Set the kind of MAC this helper will create.
void SetAddressGenerator(Ptr< LoraDeviceAddressGenerator > addrGen)
Set the address generator to use for creation of these nodes.
static std::vector< int > SetSpreadingFactorsUp(NodeContainer endDevices, NodeContainer gateways, Ptr< LoraChannel > channel)
Initialize the end devices' data rate parameter.
void ApplyCommonEuConfigurations(Ptr< LorawanMac > lorawanMac) const
Apply configurations that are common both for the GatewayLorawanMac and the ClassAEndDeviceLorawanMac...
enum Regions m_region
The region in which the device will operate.
Regions
Define the operational region.
void SetRegion(enum Regions region)
Set the region in which the device is to operate.
void Set(std::string name, const AttributeValue &v)
Set an attribute of the underlying MAC object.
ObjectFactory m_mac
MAC-layer object factory.
static std::vector< int > SetSpreadingFactorsGivenDistribution(NodeContainer endDevices, NodeContainer gateways, std::vector< double > distribution)
Randomly initialize the end devices' data rate parameter according to the given distribution.
Ptr< LoraDeviceAddressGenerator > m_addrGen
Pointer to the address generator to use.
void ConfigureForSingleChannelRegion(Ptr< ClassAEndDeviceLorawanMac > edMac) const
Perform region-specific configurations for the SINGLECHANNEL band.
void ApplyCommonSingleChannelConfigurations(Ptr< LorawanMac > lorawanMac) const
Apply configurations that are common both for the GatewayLorawanMac and the ClassAEndDeviceLorawanMac...
DeviceType
Define the kind of device.
void ApplyCommonAlohaConfigurations(Ptr< LorawanMac > lorawanMac) const
Apply configurations that are common both for the GatewayLorawanMac and the ClassAEndDeviceLorawanMac...
Ptr< LorawanMac > Install(Ptr< Node > node, Ptr< NetDevice > device) const
Create the LorawanMac instance and connect it to a device.
enum DeviceType m_deviceType
The kind of device to install.
void ConfigureForEuRegion(Ptr< ClassAEndDeviceLorawanMac > edMac) const
Perform region-specific configurations for the 868 MHz EU band.
Class representing the LoRaWAN MAC layer.
Definition lorawan-mac.h:37
std::array< std::array< uint8_t, 6 >, 8 > ReplyDataRateMatrix
Matrix structure to store possible data rate value to be used by a LoRaWAN end device for listening d...
Definition lorawan-mac.h:53
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580