From da17109d7564e96b9f2725605c09626eab3c8811 Mon Sep 17 00:00:00 2001 From: Alessandro Aimi Date: Thu, 12 Oct 2023 13:38:24 +0200 Subject: [PATCH] Apply .clang-format to all files (#138) --- doc/lorawan.rst | 14 +- examples/adr-example.cc | 507 ++-- examples/aloha-throughput.cc | 478 ++-- examples/complete-network-example.cc | 487 ++-- examples/frame-counter-update.cc | 358 ++- examples/lorawan-energy-model-example.cc | 285 +- examples/network-server-example.cc | 324 +-- examples/parallel-reception-example.cc | 262 +- examples/simple-network-example.cc | 247 +- helper/forwarder-helper.cc | 90 +- helper/forwarder-helper.h | 35 +- helper/lora-helper.cc | 428 ++- helper/lora-helper.h | 201 +- helper/lora-packet-tracker.cc | 423 ++- helper/lora-packet-tracker.h | 238 +- helper/lora-phy-helper.cc | 138 +- helper/lora-phy-helper.h | 189 +- helper/lora-radio-energy-model-helper.cc | 119 +- helper/lora-radio-energy-model-helper.h | 168 +- helper/lorawan-mac-helper.cc | 925 +++---- helper/lorawan-mac-helper.h | 288 +- helper/network-server-helper.cc | 140 +- helper/network-server-helper.h | 83 +- helper/one-shot-sender-helper.cc | 62 +- helper/one-shot-sender-helper.h | 39 +- helper/periodic-sender-helper.cc | 130 +- helper/periodic-sender-helper.h | 70 +- model/adr-component.cc | 539 ++-- model/adr-component.h | 127 +- model/building-penetration-loss.cc | 250 +- model/building-penetration-loss.h | 134 +- model/class-a-end-device-lorawan-mac.cc | 670 ++--- model/class-a-end-device-lorawan-mac.h | 360 +-- ...elated-shadowing-propagation-loss-model.cc | 379 +-- ...related-shadowing-propagation-loss-model.h | 265 +- model/end-device-lora-phy.cc | 178 +- model/end-device-lora-phy.h | 411 +-- model/end-device-lorawan-mac.cc | 1104 ++++---- model/end-device-lorawan-mac.h | 937 +++---- model/end-device-status.cc | 439 +-- model/end-device-status.h | 513 ++-- model/forwarder.cc | 93 +- model/forwarder.h | 130 +- model/gateway-lora-phy.cc | 160 +- model/gateway-lora-phy.h | 264 +- model/gateway-lorawan-mac.cc | 167 +- model/gateway-lorawan-mac.h | 59 +- model/gateway-status.cc | 111 +- model/gateway-status.h | 132 +- model/hex-grid-position-allocator.cc | 165 +- model/hex-grid-position-allocator.h | 28 +- model/logical-lora-channel-helper.cc | 278 +- model/logical-lora-channel-helper.h | 328 +-- model/logical-lora-channel.cc | 115 +- model/logical-lora-channel.h | 190 +- model/lora-channel.cc | 247 +- model/lora-channel.h | 278 +- model/lora-device-address-generator.cc | 62 +- model/lora-device-address-generator.h | 104 +- model/lora-device-address.cc | 251 +- model/lora-device-address.h | 331 +-- model/lora-frame-header.cc | 720 +++-- model/lora-frame-header.h | 591 ++-- model/lora-interference-helper.cc | 435 +-- model/lora-interference-helper.h | 308 ++- model/lora-net-device.cc | 284 +- model/lora-net-device.h | 252 +- model/lora-phy.cc | 248 +- model/lora-phy.h | 562 ++-- model/lora-radio-energy-model.cc | 500 ++-- model/lora-radio-energy-model.h | 558 ++-- model/lora-tag.cc | 119 +- model/lora-tag.h | 204 +- model/lora-tx-current-model.cc | 177 +- model/lora-tx-current-model.h | 185 +- model/lora-utils.cc | 31 +- model/lora-utils.h | 18 +- model/lorawan-mac-header.cc | 135 +- model/lorawan-mac-header.h | 210 +- model/lorawan-mac.cc | 162 +- model/lorawan-mac.h | 485 ++-- model/mac-command.cc | 1163 ++++---- model/mac-command.h | 842 +++--- model/network-controller-components.cc | 206 +- model/network-controller-components.h | 169 +- model/network-controller.cc | 72 +- model/network-controller.h | 61 +- model/network-scheduler.cc | 184 +- model/network-scheduler.h | 66 +- model/network-server.cc | 197 +- model/network-server.h | 143 +- model/network-status.cc | 272 +- model/network-status.h | 162 +- model/one-shot-sender.cc | 97 +- model/one-shot-sender.h | 83 +- model/periodic-sender.cc | 163 +- model/periodic-sender.h | 174 +- model/simple-end-device-lora-phy.cc | 318 +-- model/simple-end-device-lora-phy.h | 55 +- model/simple-gateway-lora-phy.cc | 336 +-- model/simple-gateway-lora-phy.h | 46 +- model/sub-band.cc | 134 +- model/sub-band.h | 209 +- test/lorawan-test-suite.cc | 2405 +++++++++-------- test/network-scheduler-test-suite.cc | 41 +- test/network-server-test-suite.cc | 331 +-- test/network-status-test-suite.cc | 86 +- test/utilities.cc | 155 +- test/utilities.h | 39 +- 109 files changed, 15683 insertions(+), 15237 deletions(-) diff --git a/doc/lorawan.rst b/doc/lorawan.rst index a0d2c85211..3a32440c12 100644 --- a/doc/lorawan.rst +++ b/doc/lorawan.rst @@ -103,7 +103,7 @@ To represent these two models, the module features two generic ``LoraPhy`` and model the peculiarities of the two wireless network devices: the End Device (ED) and the Gateway (GW). So, the PHY layers can be modeled by use of ``EndDeviceLoraPhy`` and ``GatewayLoraPhy`` classes, while objects of class -``EndDeviceLorawanMac``, ``ClassAEndDeviceLorawanMac``, and ``GatewayLorawanMac`` +``EndDeviceLorawanMac``, ``ClassAEndDeviceLorawanMac``, and ``GatewayLorawanMac`` are used to represent the MAC layer. A ``NetworkServer`` application can also be installed on a node that will then administer the wireless network through the GW's forwarding application, ``Forwarder``, which leverages the gateway's LoRa @@ -187,12 +187,12 @@ and forwarded to the MAC layer. \begin{matrix} & \scriptstyle{\rm SF7 } & \scriptstyle{\rm SF8 }& \scriptstyle{\rm SF9 }& \scriptstyle{\rm SF10} & \scriptstyle{\rm SF11} & \scriptstyle{\rm SF12}\\ - \scriptstyle{\rm SF7 }& 6 &-16 &-18 &-19 &-19 &-20\\ - \scriptstyle{\rm SF8 }& -24 &6 &-20 &-22 &-22 &-22\\ - \scriptstyle{\rm SF9 }& -27 &-27 &6 &-23 &-25 &-25\\ - \scriptstyle{\rm SF10} & -30 &-30 &-30 &6 &-26 &-28\\ - \scriptstyle{\rm SF11} & -33 &-33 &-33 &-33 &6 &-29\\ - \scriptstyle{\rm SF12} & -36 &-36 &-36 &-36 &-36 &6\\ + \scriptstyle{\rm SF7 }& 6 &-16 &-18 &-19 &-19 &-20\\ + \scriptstyle{\rm SF8 }& -24 &6 &-20 &-22 &-22 &-22\\ + \scriptstyle{\rm SF9 }& -27 &-27 &6 &-23 &-25 &-25\\ + \scriptstyle{\rm SF10} & -30 &-30 &-30 &6 &-26 &-28\\ + \scriptstyle{\rm SF11} & -33 &-33 &-33 &-33 &6 &-29\\ + \scriptstyle{\rm SF12} & -36 &-36 &-36 &-36 &-36 &6\\ \end{matrix} A full description of the link layer model can also be found in diff --git a/examples/adr-example.cc b/examples/adr-example.cc index 75d4d516c9..a132fd23e6 100644 --- a/examples/adr-example.cc +++ b/examples/adr-example.cc @@ -3,286 +3,295 @@ * the Spreading Factors of the devices in the Network. */ -#include "ns3/point-to-point-module.h" +#include "ns3/command-line.h" +#include "ns3/config.h" +#include "ns3/core-module.h" #include "ns3/forwarder-helper.h" -#include "ns3/network-server-helper.h" +#include "ns3/gateway-lora-phy.h" +#include "ns3/hex-grid-position-allocator.h" +#include "ns3/log.h" #include "ns3/lora-channel.h" -#include "ns3/mobility-helper.h" +#include "ns3/lora-device-address-generator.h" +#include "ns3/lora-helper.h" #include "ns3/lora-phy-helper.h" #include "ns3/lorawan-mac-helper.h" -#include "ns3/lora-helper.h" -#include "ns3/gateway-lora-phy.h" -#include "ns3/periodic-sender.h" -#include "ns3/periodic-sender-helper.h" -#include "ns3/log.h" -#include "ns3/string.h" -#include "ns3/command-line.h" -#include "ns3/core-module.h" +#include "ns3/mobility-helper.h" #include "ns3/network-module.h" -#include "ns3/lora-device-address-generator.h" +#include "ns3/network-server-helper.h" +#include "ns3/periodic-sender-helper.h" +#include "ns3/periodic-sender.h" +#include "ns3/point-to-point-module.h" #include "ns3/random-variable-stream.h" -#include "ns3/config.h" #include "ns3/rectangle.h" -#include "ns3/hex-grid-position-allocator.h" +#include "ns3/string.h" using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("AdrExample"); +NS_LOG_COMPONENT_DEFINE("AdrExample"); // Trace sources that are called when a node changes its DR or TX power -void OnDataRateChange (uint8_t oldDr, uint8_t newDr) +void +OnDataRateChange(uint8_t oldDr, uint8_t newDr) { - NS_LOG_DEBUG ("DR" << unsigned(oldDr) << " -> DR" << unsigned(newDr)); + NS_LOG_DEBUG("DR" << unsigned(oldDr) << " -> DR" << unsigned(newDr)); } -void OnTxPowerChange (double oldTxPower, double newTxPower) + +void +OnTxPowerChange(double oldTxPower, double newTxPower) { - NS_LOG_DEBUG (oldTxPower << " dBm -> " << newTxPower << " dBm"); + NS_LOG_DEBUG(oldTxPower << " dBm -> " << newTxPower << " dBm"); } -int main (int argc, char *argv[]) +int +main(int argc, char* argv[]) { - - bool verbose = false; - bool adrEnabled = true; - bool initializeSF = false; - int nDevices = 400; - int nPeriods = 20; - double mobileNodeProbability = 0; - double sideLength = 10000; - int gatewayDistance = 5000; - double maxRandomLoss = 10; - double minSpeed = 2; - double maxSpeed = 16; - std::string adrType = "ns3::AdrComponent"; - - CommandLine cmd; - cmd.AddValue ("verbose", "Whether to print output or not", verbose); - cmd.AddValue ("MultipleGwCombiningMethod", - "ns3::AdrComponent::MultipleGwCombiningMethod"); - cmd.AddValue ("MultiplePacketsCombiningMethod", - "ns3::AdrComponent::MultiplePacketsCombiningMethod"); - cmd.AddValue ("HistoryRange", "ns3::AdrComponent::HistoryRange"); - cmd.AddValue ("MType", "ns3::EndDeviceLorawanMac::MType"); - cmd.AddValue ("EDDRAdaptation", "ns3::EndDeviceLorawanMac::EnableEDDataRateAdaptation"); - cmd.AddValue ("ChangeTransmissionPower", - "ns3::AdrComponent::ChangeTransmissionPower"); - cmd.AddValue ("AdrEnabled", "Whether to enable ADR", adrEnabled); - cmd.AddValue ("nDevices", "Number of devices to simulate", nDevices); - cmd.AddValue ("PeriodsToSimulate", "Number of periods to simulate", nPeriods); - cmd.AddValue ("MobileNodeProbability", + bool verbose = false; + bool adrEnabled = true; + bool initializeSF = false; + int nDevices = 400; + int nPeriods = 20; + double mobileNodeProbability = 0; + double sideLength = 10000; + int gatewayDistance = 5000; + double maxRandomLoss = 10; + double minSpeed = 2; + double maxSpeed = 16; + std::string adrType = "ns3::AdrComponent"; + + CommandLine cmd; + cmd.AddValue("verbose", "Whether to print output or not", verbose); + cmd.AddValue("MultipleGwCombiningMethod", "ns3::AdrComponent::MultipleGwCombiningMethod"); + cmd.AddValue("MultiplePacketsCombiningMethod", + "ns3::AdrComponent::MultiplePacketsCombiningMethod"); + cmd.AddValue("HistoryRange", "ns3::AdrComponent::HistoryRange"); + cmd.AddValue("MType", "ns3::EndDeviceLorawanMac::MType"); + cmd.AddValue("EDDRAdaptation", "ns3::EndDeviceLorawanMac::EnableEDDataRateAdaptation"); + cmd.AddValue("ChangeTransmissionPower", "ns3::AdrComponent::ChangeTransmissionPower"); + cmd.AddValue("AdrEnabled", "Whether to enable ADR", adrEnabled); + cmd.AddValue("nDevices", "Number of devices to simulate", nDevices); + cmd.AddValue("PeriodsToSimulate", "Number of periods to simulate", nPeriods); + cmd.AddValue("MobileNodeProbability", "Probability of a node being a mobile node", mobileNodeProbability); - cmd.AddValue ("sideLength", + cmd.AddValue("sideLength", "Length of the side of the rectangle nodes will be placed in", sideLength); - cmd.AddValue ("maxRandomLoss", + cmd.AddValue("maxRandomLoss", "Maximum amount in dB of the random loss component", maxRandomLoss); - cmd.AddValue ("gatewayDistance", - "Distance between gateways", - gatewayDistance); - cmd.AddValue ("initializeSF", - "Whether to initialize the SFs", - initializeSF); - cmd.AddValue ("MinSpeed", - "Minimum speed for mobile devices", - minSpeed); - cmd.AddValue ("MaxSpeed", - "Maximum speed for mobile devices", - maxSpeed); - cmd.AddValue ("MaxTransmissions", - "ns3::EndDeviceLorawanMac::MaxTransmissions"); - cmd.Parse (argc, argv); - - int gatewayRings = 2 + (std::sqrt(2) * sideLength) / (gatewayDistance); - int nGateways = 3*gatewayRings*gatewayRings-3*gatewayRings+1; - - // Logging - ////////// - - LogComponentEnable ("AdrExample", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL); - // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL); - // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL); - // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL); - // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL); - LogComponentEnable ("AdrComponent", LOG_LEVEL_ALL); - // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL); - // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL); - // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - // Set the EDs to require Data Rate control from the NS - Config::SetDefault ("ns3::EndDeviceLorawanMac::DRControl", BooleanValue (true)); - - // Create a simple wireless channel - /////////////////////////////////// - - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr x = CreateObject (); - x->SetAttribute ("Min", DoubleValue (0.0)); - x->SetAttribute ("Max", DoubleValue (maxRandomLoss)); - - Ptr randomLoss = CreateObject (); - randomLoss->SetAttribute ("Variable", PointerValue (x)); - - loss->SetNext (randomLoss); - - Ptr delay = CreateObject (); - - Ptr channel = CreateObject (loss, delay); - - // Helpers - ////////// - - // End Device mobility - MobilityHelper mobilityEd, mobilityGw; - mobilityEd.SetPositionAllocator ("ns3::RandomRectanglePositionAllocator", - "X", PointerValue (CreateObjectWithAttributes - ("Min", DoubleValue(-sideLength), - "Max", DoubleValue(sideLength))), - "Y", PointerValue (CreateObjectWithAttributes - ("Min", DoubleValue(-sideLength), - "Max", DoubleValue(sideLength)))); - - // // Gateway mobility - // Ptr positionAllocGw = CreateObject (); - // positionAllocGw->Add (Vector (0.0, 0.0, 15.0)); - // positionAllocGw->Add (Vector (-5000.0, -5000.0, 15.0)); - // positionAllocGw->Add (Vector (-5000.0, 5000.0, 15.0)); - // positionAllocGw->Add (Vector (5000.0, -5000.0, 15.0)); - // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0)); - // mobilityGw.SetPositionAllocator (positionAllocGw); - // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - Ptr hexAllocator = CreateObject (gatewayDistance / 2); - mobilityGw.SetPositionAllocator (hexAllocator); - mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); - - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - helper.EnablePacketTracking (); - - //////////////// - // Create GWs // - //////////////// - - NodeContainer gateways; - gateways.Create (nGateways); - mobilityGw.Install (gateways); - - // Create the LoraNetDevices of the gateways - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - // Create EDs - ///////////// - - NodeContainer endDevices; - endDevices.Create (nDevices); - - // Install mobility model on fixed nodes - mobilityEd.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - int fixedPositionNodes = double (nDevices) * (1 - mobileNodeProbability); - for (int i = 0; i < fixedPositionNodes; ++i) + cmd.AddValue("gatewayDistance", "Distance between gateways", gatewayDistance); + cmd.AddValue("initializeSF", "Whether to initialize the SFs", initializeSF); + cmd.AddValue("MinSpeed", "Minimum speed for mobile devices", minSpeed); + cmd.AddValue("MaxSpeed", "Maximum speed for mobile devices", maxSpeed); + cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions"); + cmd.Parse(argc, argv); + + int gatewayRings = 2 + (std::sqrt(2) * sideLength) / (gatewayDistance); + int nGateways = 3 * gatewayRings * gatewayRings - 3 * gatewayRings + 1; + + // Logging + ////////// + + LogComponentEnable("AdrExample", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraPacketTracker", LOG_LEVEL_ALL); + // LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL); + // LogComponentEnable ("NetworkController", LOG_LEVEL_ALL); + // LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL); + // LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL); + LogComponentEnable("AdrComponent", LOG_LEVEL_ALL); + // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("MacCommand", LOG_LEVEL_ALL); + // LogComponentEnable ("AdrExploraSf", LOG_LEVEL_ALL); + // LogComponentEnable ("AdrExploraAt", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + // Set the EDs to require Data Rate control from the NS + Config::SetDefault("ns3::EndDeviceLorawanMac::DRControl", BooleanValue(true)); + + // Create a simple wireless channel + /////////////////////////////////// + + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr x = CreateObject(); + x->SetAttribute("Min", DoubleValue(0.0)); + x->SetAttribute("Max", DoubleValue(maxRandomLoss)); + + Ptr randomLoss = CreateObject(); + randomLoss->SetAttribute("Variable", PointerValue(x)); + + loss->SetNext(randomLoss); + + Ptr delay = CreateObject(); + + Ptr channel = CreateObject(loss, delay); + + // Helpers + ////////// + + // End Device mobility + MobilityHelper mobilityEd, mobilityGw; + mobilityEd.SetPositionAllocator( + "ns3::RandomRectanglePositionAllocator", + "X", + PointerValue(CreateObjectWithAttributes("Min", + DoubleValue(-sideLength), + "Max", + DoubleValue(sideLength))), + "Y", + PointerValue(CreateObjectWithAttributes("Min", + DoubleValue(-sideLength), + "Max", + DoubleValue(sideLength)))); + + // // Gateway mobility + // Ptr positionAllocGw = CreateObject (); + // positionAllocGw->Add (Vector (0.0, 0.0, 15.0)); + // positionAllocGw->Add (Vector (-5000.0, -5000.0, 15.0)); + // positionAllocGw->Add (Vector (-5000.0, 5000.0, 15.0)); + // positionAllocGw->Add (Vector (5000.0, -5000.0, 15.0)); + // positionAllocGw->Add (Vector (5000.0, 5000.0, 15.0)); + // mobilityGw.SetPositionAllocator (positionAllocGw); + // mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + Ptr hexAllocator = + CreateObject(gatewayDistance / 2); + mobilityGw.SetPositionAllocator(hexAllocator); + mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); + + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); + + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + helper.EnablePacketTracking(); + + //////////////// + // Create GWs // + //////////////// + + NodeContainer gateways; + gateways.Create(nGateways); + mobilityGw.Install(gateways); + + // Create the LoraNetDevices of the gateways + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + // Create EDs + ///////////// + + NodeContainer endDevices; + endDevices.Create(nDevices); + + // Install mobility model on fixed nodes + mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + int fixedPositionNodes = double(nDevices) * (1 - mobileNodeProbability); + for (int i = 0; i < fixedPositionNodes; ++i) { - mobilityEd.Install (endDevices.Get (i)); + mobilityEd.Install(endDevices.Get(i)); } - // Install mobility model on mobile nodes - mobilityEd.SetMobilityModel ("ns3::RandomWalk2dMobilityModel", - "Bounds", RectangleValue (Rectangle (-sideLength, sideLength, - -sideLength, sideLength)), - "Distance", DoubleValue (1000), - "Speed", PointerValue (CreateObjectWithAttributes - ("Min", DoubleValue(minSpeed), - "Max", DoubleValue(maxSpeed)))); - for (int i = fixedPositionNodes; i < (int) endDevices.GetN (); ++i) + // Install mobility model on mobile nodes + mobilityEd.SetMobilityModel( + "ns3::RandomWalk2dMobilityModel", + "Bounds", + RectangleValue(Rectangle(-sideLength, sideLength, -sideLength, sideLength)), + "Distance", + DoubleValue(1000), + "Speed", + PointerValue(CreateObjectWithAttributes("Min", + DoubleValue(minSpeed), + "Max", + DoubleValue(maxSpeed)))); + for (int i = fixedPositionNodes; i < (int)endDevices.GetN(); ++i) { - mobilityEd.Install (endDevices.Get (i)); + mobilityEd.Install(endDevices.Get(i)); } - // Create a LoraDeviceAddressGenerator - uint8_t nwkId = 54; - uint32_t nwkAddr = 1864; - Ptr addrGen = CreateObject (nwkId,nwkAddr); - - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - macHelper.SetAddressGenerator (addrGen); - macHelper.SetRegion (LorawanMacHelper::EU); - helper.Install (phyHelper, macHelper, endDevices); - - // Install applications in EDs - int appPeriodSeconds = 1200; // One packet every 20 minutes - PeriodicSenderHelper appHelper = PeriodicSenderHelper (); - appHelper.SetPeriod (Seconds (appPeriodSeconds)); - ApplicationContainer appContainer = appHelper.Install (endDevices); - - // Do not set spreading factors up: we will wait for the NS to do this - if (initializeSF) + // Create a LoraDeviceAddressGenerator + uint8_t nwkId = 54; + uint32_t nwkAddr = 1864; + Ptr addrGen = + CreateObject(nwkId, nwkAddr); + + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + macHelper.SetAddressGenerator(addrGen); + macHelper.SetRegion(LorawanMacHelper::EU); + helper.Install(phyHelper, macHelper, endDevices); + + // Install applications in EDs + int appPeriodSeconds = 1200; // One packet every 20 minutes + PeriodicSenderHelper appHelper = PeriodicSenderHelper(); + appHelper.SetPeriod(Seconds(appPeriodSeconds)); + ApplicationContainer appContainer = appHelper.Install(endDevices); + + // Do not set spreading factors up: we will wait for the NS to do this + if (initializeSF) { - macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); + macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); } - //////////// - // Create NS - //////////// - - NodeContainer networkServers; - networkServers.Create (1); - - // Install the NetworkServer application on the network server - NetworkServerHelper networkServerHelper; - networkServerHelper.SetGateways (gateways); - networkServerHelper.SetEndDevices (endDevices); - networkServerHelper.EnableAdr (adrEnabled); - networkServerHelper.SetAdr (adrType); - networkServerHelper.Install (networkServers); - - // Install the Forwarder application on the gateways - ForwarderHelper forwarderHelper; - forwarderHelper.Install (gateways); - - // Connect our traces - Config::ConnectWithoutContext ("/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower", - MakeCallback (&OnTxPowerChange)); - Config::ConnectWithoutContext ("/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate", - MakeCallback (&OnDataRateChange)); - - // Activate printing of ED MAC parameters - Time stateSamplePeriod = Seconds (1200); - helper.EnablePeriodicDeviceStatusPrinting (endDevices, gateways, "nodeData.txt", stateSamplePeriod); - helper.EnablePeriodicPhyPerformancePrinting (gateways, "phyPerformance.txt", stateSamplePeriod); - helper.EnablePeriodicGlobalPerformancePrinting ("globalPerformance.txt", stateSamplePeriod); - - LoraPacketTracker& tracker = helper.GetPacketTracker (); - - // Start simulation - Time simulationTime = Seconds (1200 * nPeriods); - Simulator::Stop (simulationTime); - Simulator::Run (); - Simulator::Destroy (); - - std::cout << tracker.CountMacPacketsGlobally(Seconds (1200 * (nPeriods - 2)), - Seconds (1200 * (nPeriods - 1))) << std::endl; - - return 0; + //////////// + // Create NS + //////////// + + NodeContainer networkServers; + networkServers.Create(1); + + // Install the NetworkServer application on the network server + NetworkServerHelper networkServerHelper; + networkServerHelper.SetGateways(gateways); + networkServerHelper.SetEndDevices(endDevices); + networkServerHelper.EnableAdr(adrEnabled); + networkServerHelper.SetAdr(adrType); + networkServerHelper.Install(networkServers); + + // Install the Forwarder application on the gateways + ForwarderHelper forwarderHelper; + forwarderHelper.Install(gateways); + + // Connect our traces + Config::ConnectWithoutContext( + "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/TxPower", + MakeCallback(&OnTxPowerChange)); + Config::ConnectWithoutContext( + "/NodeList/*/DeviceList/0/$ns3::LoraNetDevice/Mac/$ns3::EndDeviceLorawanMac/DataRate", + MakeCallback(&OnDataRateChange)); + + // Activate printing of ED MAC parameters + Time stateSamplePeriod = Seconds(1200); + helper.EnablePeriodicDeviceStatusPrinting(endDevices, + gateways, + "nodeData.txt", + stateSamplePeriod); + helper.EnablePeriodicPhyPerformancePrinting(gateways, "phyPerformance.txt", stateSamplePeriod); + helper.EnablePeriodicGlobalPerformancePrinting("globalPerformance.txt", stateSamplePeriod); + + LoraPacketTracker& tracker = helper.GetPacketTracker(); + + // Start simulation + Time simulationTime = Seconds(1200 * nPeriods); + Simulator::Stop(simulationTime); + Simulator::Run(); + Simulator::Destroy(); + + std::cout << tracker.CountMacPacketsGlobally(Seconds(1200 * (nPeriods - 2)), + Seconds(1200 * (nPeriods - 1))) + << std::endl; + + return 0; } diff --git a/examples/aloha-throughput.cc b/examples/aloha-throughput.cc index 1353d02aab..7bb04709bd 100644 --- a/examples/aloha-throughput.cc +++ b/examples/aloha-throughput.cc @@ -1,38 +1,39 @@ +#include "ns3/building-allocator.h" +#include "ns3/building-penetration-loss.h" +#include "ns3/buildings-helper.h" #include "ns3/callback.h" +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" +#include "ns3/correlated-shadowing-propagation-loss-model.h" +#include "ns3/double.h" #include "ns3/end-device-lora-phy.h" -#include "ns3/gateway-lora-phy.h" #include "ns3/end-device-lorawan-mac.h" +#include "ns3/forwarder-helper.h" +#include "ns3/gateway-lora-phy.h" #include "ns3/gateway-lorawan-mac.h" +#include "ns3/log.h" #include "ns3/lora-device-address.h" #include "ns3/lora-frame-header.h" +#include "ns3/lora-helper.h" #include "ns3/lora-net-device.h" #include "ns3/lora-phy.h" #include "ns3/lorawan-mac-header.h" -#include "ns3/simulator.h" -#include "ns3/log.h" -#include "ns3/pointer.h" -#include "ns3/constant-position-mobility-model.h" -#include "ns3/lora-helper.h" -#include "ns3/node-container.h" #include "ns3/mobility-helper.h" +#include "ns3/network-server-helper.h" +#include "ns3/node-container.h" +#include "ns3/periodic-sender-helper.h" +#include "ns3/pointer.h" #include "ns3/position-allocator.h" -#include "ns3/double.h" #include "ns3/random-variable-stream.h" -#include "ns3/periodic-sender-helper.h" -#include "ns3/command-line.h" -#include "ns3/network-server-helper.h" -#include "ns3/correlated-shadowing-propagation-loss-model.h" -#include "ns3/building-penetration-loss.h" -#include "ns3/building-allocator.h" -#include "ns3/buildings-helper.h" -#include "ns3/forwarder-helper.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("AlohaThroughput"); +NS_LOG_COMPONENT_DEFINE("AlohaThroughput"); // Network settings int nDevices = 200; @@ -43,281 +44,288 @@ double simulationTime = 100; // Channel model bool realisticChannelModel = false; -std::vector packetsSent (6, 0); -std::vector packetsReceived (6, 0); +std::vector packetsSent(6, 0); +std::vector packetsReceived(6, 0); void -OnTransmissionCallback (Ptr packet, uint32_t systemId) +OnTransmissionCallback(Ptr packet, uint32_t systemId) { - NS_LOG_FUNCTION (packet << systemId); - LoraTag tag; - packet->PeekPacketTag(tag); - packetsSent.at(tag.GetSpreadingFactor()-7)++; + NS_LOG_FUNCTION(packet << systemId); + LoraTag tag; + packet->PeekPacketTag(tag); + packetsSent.at(tag.GetSpreadingFactor() - 7)++; } void -OnPacketReceptionCallback (Ptr packet, uint32_t systemId) +OnPacketReceptionCallback(Ptr packet, uint32_t systemId) { - NS_LOG_FUNCTION (packet << systemId); - LoraTag tag; - packet->PeekPacketTag(tag); - packetsReceived.at(tag.GetSpreadingFactor()-7)++; + NS_LOG_FUNCTION(packet << systemId); + LoraTag tag; + packet->PeekPacketTag(tag); + packetsReceived.at(tag.GetSpreadingFactor() - 7)++; } int -main (int argc, char *argv[]) +main(int argc, char* argv[]) { + std::string interferenceMatrix = "aloha"; - std::string interferenceMatrix = "aloha"; - - CommandLine cmd; - cmd.AddValue ("nDevices", "Number of end devices to include in the simulation", nDevices); - cmd.AddValue ("simulationTime", "Simulation Time", simulationTime); - cmd.AddValue ("interferenceMatrix", "Interference matrix to use [aloha, goursaud]", interferenceMatrix); - cmd.AddValue ("radius", "Radius of the deployment", radius); - cmd.Parse (argc, argv); - - int appPeriodSeconds = simulationTime; - - // Set up logging - LogComponentEnable ("AlohaThroughput", LOG_LEVEL_ALL); + CommandLine cmd; + cmd.AddValue("nDevices", "Number of end devices to include in the simulation", nDevices); + cmd.AddValue("simulationTime", "Simulation Time", simulationTime); + cmd.AddValue("interferenceMatrix", + "Interference matrix to use [aloha, goursaud]", + interferenceMatrix); + cmd.AddValue("radius", "Radius of the deployment", radius); + cmd.Parse(argc, argv); - // Make all devices use SF7 (i.e., DR5) - // Config::SetDefault ("ns3::EndDeviceLorawanMac::DataRate", UintegerValue (5)); + int appPeriodSeconds = simulationTime; - if (interferenceMatrix == "aloha") - { - LoraInterferenceHelper::collisionMatrix = LoraInterferenceHelper::ALOHA; - } - else if (interferenceMatrix == "goursaud") - { - LoraInterferenceHelper::collisionMatrix = LoraInterferenceHelper::GOURSAUD; - } + // Set up logging + LogComponentEnable("AlohaThroughput", LOG_LEVEL_ALL); - /*********** - * Setup * - ***********/ + // Make all devices use SF7 (i.e., DR5) + // Config::SetDefault ("ns3::EndDeviceLorawanMac::DataRate", UintegerValue (5)); - // Mobility - MobilityHelper mobility; - mobility.SetPositionAllocator ("ns3::UniformDiscPositionAllocator", "rho", DoubleValue (radius), - "X", DoubleValue (0.0), "Y", DoubleValue (0.0)); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - /************************ - * Create the channel * - ************************/ - - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); + if (interferenceMatrix == "aloha") + { + LoraInterferenceHelper::collisionMatrix = LoraInterferenceHelper::ALOHA; + } + else if (interferenceMatrix == "goursaud") + { + LoraInterferenceHelper::collisionMatrix = LoraInterferenceHelper::GOURSAUD; + } - if (realisticChannelModel) + /*********** + * Setup * + ***********/ + + // Mobility + MobilityHelper mobility; + mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator", + "rho", + DoubleValue(radius), + "X", + DoubleValue(0.0), + "Y", + DoubleValue(0.0)); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + /************************ + * Create the channel * + ************************/ + + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + if (realisticChannelModel) { - // Create the correlated shadowing component - Ptr shadowing = - CreateObject (); + // Create the correlated shadowing component + Ptr shadowing = + CreateObject(); - // Aggregate shadowing to the logdistance loss - loss->SetNext (shadowing); + // Aggregate shadowing to the logdistance loss + loss->SetNext(shadowing); - // Add the effect to the channel propagation loss - Ptr buildingLoss = CreateObject (); + // Add the effect to the channel propagation loss + Ptr buildingLoss = CreateObject(); - shadowing->SetNext (buildingLoss); + shadowing->SetNext(buildingLoss); } - Ptr delay = CreateObject (); + Ptr delay = CreateObject(); - Ptr channel = CreateObject (loss, delay); + Ptr channel = CreateObject(loss, delay); - /************************ - * Create the helpers * - ************************/ + /************************ + * Create the helpers * + ************************/ - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - macHelper.SetRegion (LorawanMacHelper::ALOHA); + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); + macHelper.SetRegion(LorawanMacHelper::ALOHA); - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - helper.EnablePacketTracking (); // Output filename + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + helper.EnablePacketTracking(); // Output filename - //Create the NetworkServerHelper - NetworkServerHelper nsHelper = NetworkServerHelper (); + // Create the NetworkServerHelper + NetworkServerHelper nsHelper = NetworkServerHelper(); - //Create the ForwarderHelper - ForwarderHelper forHelper = ForwarderHelper (); + // Create the ForwarderHelper + ForwarderHelper forHelper = ForwarderHelper(); - /************************ - * Create End Devices * - ************************/ + /************************ + * Create End Devices * + ************************/ - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (nDevices); + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(nDevices); - // Assign a mobility model to each node - mobility.Install (endDevices); + // Assign a mobility model to each node + mobility.Install(endDevices); - // Make it so that nodes are at a certain height > 0 - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Make it so that nodes are at a certain height > 0 + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr mobility = (*j)->GetObject (); - Vector position = mobility->GetPosition (); - position.z = 1.2; - mobility->SetPosition (position); + Ptr mobility = (*j)->GetObject(); + Vector position = mobility->GetPosition(); + position.z = 1.2; + mobility->SetPosition(position); } - // Create the LoraNetDevices of the end devices - uint8_t nwkId = 54; - uint32_t nwkAddr = 1864; - Ptr addrGen = - CreateObject (nwkId, nwkAddr); + // Create the LoraNetDevices of the end devices + uint8_t nwkId = 54; + uint32_t nwkAddr = 1864; + Ptr addrGen = + CreateObject(nwkId, nwkAddr); - // Create the LoraNetDevices of the end devices - macHelper.SetAddressGenerator (addrGen); - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - helper.Install (phyHelper, macHelper, endDevices); + // Create the LoraNetDevices of the end devices + macHelper.SetAddressGenerator(addrGen); + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + helper.Install(phyHelper, macHelper, endDevices); - // Now end devices are connected to the channel + // Now end devices are connected to the channel - // Connect trace sources - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Connect trace sources + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr node = *j; - Ptr loraNetDevice = node->GetDevice (0)->GetObject (); - Ptr phy = loraNetDevice->GetPhy (); + Ptr node = *j; + Ptr loraNetDevice = node->GetDevice(0)->GetObject(); + Ptr phy = loraNetDevice->GetPhy(); } - /********************* - * Create Gateways * - *********************/ - - // Create the gateway nodes (allocate them uniformely on the disc) - NodeContainer gateways; - gateways.Create (nGateways); - - Ptr allocator = CreateObject (); - // Make it so that nodes are at a certain height > 0 - allocator->Add (Vector (0.0, 0.0, 15.0)); - mobility.SetPositionAllocator (allocator); - mobility.Install (gateways); - - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - NS_LOG_DEBUG ("Completed configuration"); - - /********************************************* - * Install applications on the end devices * - *********************************************/ - - Time appStopTime = Seconds (simulationTime); - int packetSize = 50; - PeriodicSenderHelper appHelper = PeriodicSenderHelper (); - appHelper.SetPeriod (Seconds (appPeriodSeconds)); - appHelper.SetPacketSize (packetSize); - ApplicationContainer appContainer = appHelper.Install (endDevices); - - appContainer.Start (Seconds (0)); - appContainer.Stop (appStopTime); - - - std::ofstream outputFile; - // Delete contents of the file as it is opened - outputFile.open ("durations.txt", std::ofstream::out | std::ofstream::trunc); - for (uint8_t sf = 7; sf <= 12; sf++) + /********************* + * Create Gateways * + *********************/ + + // Create the gateway nodes (allocate them uniformely on the disc) + NodeContainer gateways; + gateways.Create(nGateways); + + Ptr allocator = CreateObject(); + // Make it so that nodes are at a certain height > 0 + allocator->Add(Vector(0.0, 0.0, 15.0)); + mobility.SetPositionAllocator(allocator); + mobility.Install(gateways); + + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + NS_LOG_DEBUG("Completed configuration"); + + /********************************************* + * Install applications on the end devices * + *********************************************/ + + Time appStopTime = Seconds(simulationTime); + int packetSize = 50; + PeriodicSenderHelper appHelper = PeriodicSenderHelper(); + appHelper.SetPeriod(Seconds(appPeriodSeconds)); + appHelper.SetPacketSize(packetSize); + ApplicationContainer appContainer = appHelper.Install(endDevices); + + appContainer.Start(Seconds(0)); + appContainer.Stop(appStopTime); + + std::ofstream outputFile; + // Delete contents of the file as it is opened + outputFile.open("durations.txt", std::ofstream::out | std::ofstream::trunc); + for (uint8_t sf = 7; sf <= 12; sf++) { - LoraTxParameters txParams; - txParams.sf = sf; - txParams.headerDisabled = 0; - txParams.codingRate = 1; - txParams.bandwidthHz = 125000; - txParams.nPreamble = 8; - txParams.crcEnabled = 1; - txParams.lowDataRateOptimizationEnabled = - LoraPhy::GetTSym (txParams) > MilliSeconds (16) ? true : false; - Ptr pkt = Create (packetSize); - - LoraFrameHeader frameHdr = LoraFrameHeader (); - frameHdr.SetAsUplink (); - frameHdr.SetFPort (1); - frameHdr.SetAddress (LoraDeviceAddress ()); - frameHdr.SetAdr (0); - frameHdr.SetAdrAckReq (0); - frameHdr.SetFCnt (0); - pkt->AddHeader (frameHdr); - - LorawanMacHeader macHdr = LorawanMacHeader (); - macHdr.SetMType (ns3::lorawan::LorawanMacHeader::UNCONFIRMED_DATA_UP); - macHdr.SetMajor (1); - pkt->AddHeader (macHdr); - - outputFile << LoraPhy::GetOnAirTime (pkt, txParams).GetMicroSeconds() << " "; + LoraTxParameters txParams; + txParams.sf = sf; + txParams.headerDisabled = 0; + txParams.codingRate = 1; + txParams.bandwidthHz = 125000; + txParams.nPreamble = 8; + txParams.crcEnabled = 1; + txParams.lowDataRateOptimizationEnabled = + LoraPhy::GetTSym(txParams) > MilliSeconds(16) ? true : false; + Ptr pkt = Create(packetSize); + + LoraFrameHeader frameHdr = LoraFrameHeader(); + frameHdr.SetAsUplink(); + frameHdr.SetFPort(1); + frameHdr.SetAddress(LoraDeviceAddress()); + frameHdr.SetAdr(0); + frameHdr.SetAdrAckReq(0); + frameHdr.SetFCnt(0); + pkt->AddHeader(frameHdr); + + LorawanMacHeader macHdr = LorawanMacHeader(); + macHdr.SetMType(ns3::lorawan::LorawanMacHeader::UNCONFIRMED_DATA_UP); + macHdr.SetMajor(1); + pkt->AddHeader(macHdr); + + outputFile << LoraPhy::GetOnAirTime(pkt, txParams).GetMicroSeconds() << " "; } - outputFile.close (); + outputFile.close(); - /************************** - * Create Network Server * - ***************************/ + /************************** + * Create Network Server * + ***************************/ - // Create the NS node - NodeContainer networkServer; - networkServer.Create (1); + // Create the NS node + NodeContainer networkServer; + networkServer.Create(1); - // Create a NS for the network - nsHelper.SetEndDevices (endDevices); - nsHelper.SetGateways (gateways); - nsHelper.Install (networkServer); + // Create a NS for the network + nsHelper.SetEndDevices(endDevices); + nsHelper.SetGateways(gateways); + nsHelper.Install(networkServer); - //Create a forwarder for each gateway - forHelper.Install (gateways); + // Create a forwarder for each gateway + forHelper.Install(gateways); - // Install trace sources - for (NodeContainer::Iterator node = gateways.Begin (); node != gateways.End(); node++) - { - (*node)->GetDevice (0)->GetObject ()->GetPhy ()->TraceConnectWithoutContext ( - "ReceivedPacket", MakeCallback (OnPacketReceptionCallback)); - } + // Install trace sources + for (NodeContainer::Iterator node = gateways.Begin(); node != gateways.End(); node++) + { + (*node)->GetDevice(0)->GetObject()->GetPhy()->TraceConnectWithoutContext( + "ReceivedPacket", + MakeCallback(OnPacketReceptionCallback)); + } - // Install trace sources - for (NodeContainer::Iterator node = endDevices.Begin (); node != endDevices.End(); node++) - { - (*node)->GetDevice (0)->GetObject ()->GetPhy ()->TraceConnectWithoutContext ( - "StartSending", MakeCallback (OnTransmissionCallback)); - } + // Install trace sources + for (NodeContainer::Iterator node = endDevices.Begin(); node != endDevices.End(); node++) + { + (*node)->GetDevice(0)->GetObject()->GetPhy()->TraceConnectWithoutContext( + "StartSending", + MakeCallback(OnTransmissionCallback)); + } - macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); + macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); - //////////////// - // Simulation // - //////////////// + //////////////// + // Simulation // + //////////////// - Simulator::Stop (appStopTime + Hours (1)); + Simulator::Stop(appStopTime + Hours(1)); - NS_LOG_INFO ("Running simulation..."); - Simulator::Run (); + NS_LOG_INFO("Running simulation..."); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - ///////////////////////////// - // Print results to stdout // - ///////////////////////////// - NS_LOG_INFO ("Computing performance metrics..."); + ///////////////////////////// + // Print results to stdout // + ///////////////////////////// + NS_LOG_INFO("Computing performance metrics..."); - for (int i = 0; i < 6; i++) - { - std::cout << packetsSent.at(i) << " " << packetsReceived.at(i) << std::endl; - } + for (int i = 0; i < 6; i++) + { + std::cout << packetsSent.at(i) << " " << packetsReceived.at(i) << std::endl; + } - return 0; + return 0; } diff --git a/examples/complete-network-example.cc b/examples/complete-network-example.cc index 84f9a25a5e..9c651c9b00 100644 --- a/examples/complete-network-example.cc +++ b/examples/complete-network-example.cc @@ -4,40 +4,41 @@ * network. */ +#include "ns3/building-allocator.h" +#include "ns3/building-penetration-loss.h" +#include "ns3/buildings-helper.h" +#include "ns3/class-a-end-device-lorawan-mac.h" +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" +#include "ns3/correlated-shadowing-propagation-loss-model.h" +#include "ns3/double.h" #include "ns3/end-device-lora-phy.h" +#include "ns3/forwarder-helper.h" #include "ns3/gateway-lora-phy.h" -#include "ns3/class-a-end-device-lorawan-mac.h" #include "ns3/gateway-lorawan-mac.h" -#include "ns3/simulator.h" #include "ns3/log.h" -#include "ns3/pointer.h" -#include "ns3/constant-position-mobility-model.h" #include "ns3/lora-helper.h" -#include "ns3/node-container.h" #include "ns3/mobility-helper.h" +#include "ns3/network-server-helper.h" +#include "ns3/node-container.h" +#include "ns3/periodic-sender-helper.h" +#include "ns3/pointer.h" #include "ns3/position-allocator.h" -#include "ns3/double.h" #include "ns3/random-variable-stream.h" -#include "ns3/periodic-sender-helper.h" -#include "ns3/command-line.h" -#include "ns3/network-server-helper.h" -#include "ns3/correlated-shadowing-propagation-loss-model.h" -#include "ns3/building-penetration-loss.h" -#include "ns3/building-allocator.h" -#include "ns3/buildings-helper.h" -#include "ns3/forwarder-helper.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("ComplexLorawanNetworkExample"); +NS_LOG_COMPONENT_DEFINE("ComplexLorawanNetworkExample"); // Network settings int nDevices = 200; int nGateways = 1; -double radius = 6400; //Note that due to model updates, 7500 m is no longer the maximum distance +double radius = 6400; // Note that due to model updates, 7500 m is no longer the maximum distance double simulationTime = 600; // Channel model @@ -49,276 +50,286 @@ int appPeriodSeconds = 600; bool print = true; int -main (int argc, char *argv[]) +main(int argc, char* argv[]) { - - CommandLine cmd; - cmd.AddValue ("nDevices", "Number of end devices to include in the simulation", nDevices); - cmd.AddValue ("radius", "The radius of the area to simulate", radius); - cmd.AddValue ("simulationTime", "The time for which to simulate", simulationTime); - cmd.AddValue ("appPeriod", - "The period in seconds to be used by periodically transmitting applications", - appPeriodSeconds); - cmd.AddValue ("print", "Whether or not to print various informations", print); - cmd.Parse (argc, argv); - - // Set up logging - LogComponentEnable ("ComplexLorawanNetworkExample", LOG_LEVEL_ALL); - // LogComponentEnable("LoraChannel", LOG_LEVEL_INFO); - // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("LoraInterferenceHelper", LOG_LEVEL_ALL); - // LogComponentEnable("LorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - // LogComponentEnable("LogicalLoraChannel", LOG_LEVEL_ALL); - // LogComponentEnable("LoraHelper", LOG_LEVEL_ALL); - // LogComponentEnable("LoraPhyHelper", LOG_LEVEL_ALL); - // LogComponentEnable("LorawanMacHelper", LOG_LEVEL_ALL); - // LogComponentEnable("PeriodicSenderHelper", LOG_LEVEL_ALL); - // LogComponentEnable("PeriodicSender", LOG_LEVEL_ALL); - // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL); - // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL); - // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL); - // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL); - // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL); - // LogComponentEnable("NetworkController", LOG_LEVEL_ALL); - - /*********** - * Setup * - ***********/ - - // Create the time value from the period - Time appPeriod = Seconds (appPeriodSeconds); - - // Mobility - MobilityHelper mobility; - mobility.SetPositionAllocator ("ns3::UniformDiscPositionAllocator", "rho", DoubleValue (radius), - "X", DoubleValue (0.0), "Y", DoubleValue (0.0)); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - /************************ - * Create the channel * - ************************/ - - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - if (realisticChannelModel) + CommandLine cmd; + cmd.AddValue("nDevices", "Number of end devices to include in the simulation", nDevices); + cmd.AddValue("radius", "The radius of the area to simulate", radius); + cmd.AddValue("simulationTime", "The time for which to simulate", simulationTime); + cmd.AddValue("appPeriod", + "The period in seconds to be used by periodically transmitting applications", + appPeriodSeconds); + cmd.AddValue("print", "Whether or not to print various informations", print); + cmd.Parse(argc, argv); + + // Set up logging + LogComponentEnable("ComplexLorawanNetworkExample", LOG_LEVEL_ALL); + // LogComponentEnable("LoraChannel", LOG_LEVEL_INFO); + // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("LoraInterferenceHelper", LOG_LEVEL_ALL); + // LogComponentEnable("LorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + // LogComponentEnable("LogicalLoraChannel", LOG_LEVEL_ALL); + // LogComponentEnable("LoraHelper", LOG_LEVEL_ALL); + // LogComponentEnable("LoraPhyHelper", LOG_LEVEL_ALL); + // LogComponentEnable("LorawanMacHelper", LOG_LEVEL_ALL); + // LogComponentEnable("PeriodicSenderHelper", LOG_LEVEL_ALL); + // LogComponentEnable("PeriodicSender", LOG_LEVEL_ALL); + // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL); + // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL); + // LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL); + // LogComponentEnable("NetworkServer", LOG_LEVEL_ALL); + // LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL); + // LogComponentEnable("NetworkController", LOG_LEVEL_ALL); + + /*********** + * Setup * + ***********/ + + // Create the time value from the period + Time appPeriod = Seconds(appPeriodSeconds); + + // Mobility + MobilityHelper mobility; + mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator", + "rho", + DoubleValue(radius), + "X", + DoubleValue(0.0), + "Y", + DoubleValue(0.0)); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + /************************ + * Create the channel * + ************************/ + + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + if (realisticChannelModel) { - // Create the correlated shadowing component - Ptr shadowing = - CreateObject (); + // Create the correlated shadowing component + Ptr shadowing = + CreateObject(); - // Aggregate shadowing to the logdistance loss - loss->SetNext (shadowing); + // Aggregate shadowing to the logdistance loss + loss->SetNext(shadowing); - // Add the effect to the channel propagation loss - Ptr buildingLoss = CreateObject (); + // Add the effect to the channel propagation loss + Ptr buildingLoss = CreateObject(); - shadowing->SetNext (buildingLoss); + shadowing->SetNext(buildingLoss); } - Ptr delay = CreateObject (); + Ptr delay = CreateObject(); - Ptr channel = CreateObject (loss, delay); + Ptr channel = CreateObject(loss, delay); - /************************ - * Create the helpers * - ************************/ + /************************ + * Create the helpers * + ************************/ - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - helper.EnablePacketTracking (); // Output filename - // helper.EnableSimulationTimePrinting (); + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + helper.EnablePacketTracking(); // Output filename + // helper.EnableSimulationTimePrinting (); - //Create the NetworkServerHelper - NetworkServerHelper nsHelper = NetworkServerHelper (); + // Create the NetworkServerHelper + NetworkServerHelper nsHelper = NetworkServerHelper(); - //Create the ForwarderHelper - ForwarderHelper forHelper = ForwarderHelper (); + // Create the ForwarderHelper + ForwarderHelper forHelper = ForwarderHelper(); - /************************ - * Create End Devices * - ************************/ + /************************ + * Create End Devices * + ************************/ - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (nDevices); + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(nDevices); - // Assign a mobility model to each node - mobility.Install (endDevices); + // Assign a mobility model to each node + mobility.Install(endDevices); - // Make it so that nodes are at a certain height > 0 - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Make it so that nodes are at a certain height > 0 + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr mobility = (*j)->GetObject (); - Vector position = mobility->GetPosition (); - position.z = 1.2; - mobility->SetPosition (position); + Ptr mobility = (*j)->GetObject(); + Vector position = mobility->GetPosition(); + position.z = 1.2; + mobility->SetPosition(position); } - // Create the LoraNetDevices of the end devices - uint8_t nwkId = 54; - uint32_t nwkAddr = 1864; - Ptr addrGen = - CreateObject (nwkId, nwkAddr); + // Create the LoraNetDevices of the end devices + uint8_t nwkId = 54; + uint32_t nwkAddr = 1864; + Ptr addrGen = + CreateObject(nwkId, nwkAddr); - // Create the LoraNetDevices of the end devices - macHelper.SetAddressGenerator (addrGen); - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - helper.Install (phyHelper, macHelper, endDevices); + // Create the LoraNetDevices of the end devices + macHelper.SetAddressGenerator(addrGen); + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + helper.Install(phyHelper, macHelper, endDevices); - // Now end devices are connected to the channel + // Now end devices are connected to the channel - // Connect trace sources - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Connect trace sources + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr node = *j; - Ptr loraNetDevice = node->GetDevice (0)->GetObject (); - Ptr phy = loraNetDevice->GetPhy (); + Ptr node = *j; + Ptr loraNetDevice = node->GetDevice(0)->GetObject(); + Ptr phy = loraNetDevice->GetPhy(); } - /********************* - * Create Gateways * - *********************/ - - // Create the gateway nodes (allocate them uniformely on the disc) - NodeContainer gateways; - gateways.Create (nGateways); - - Ptr allocator = CreateObject (); - // Make it so that nodes are at a certain height > 0 - allocator->Add (Vector (0.0, 0.0, 15.0)); - mobility.SetPositionAllocator (allocator); - mobility.Install (gateways); - - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - /********************** - * Handle buildings * - **********************/ - - double xLength = 130; - double deltaX = 32; - double yLength = 64; - double deltaY = 17; - int gridWidth = 2 * radius / (xLength + deltaX); - int gridHeight = 2 * radius / (yLength + deltaY); - if (realisticChannelModel == false) + /********************* + * Create Gateways * + *********************/ + + // Create the gateway nodes (allocate them uniformely on the disc) + NodeContainer gateways; + gateways.Create(nGateways); + + Ptr allocator = CreateObject(); + // Make it so that nodes are at a certain height > 0 + allocator->Add(Vector(0.0, 0.0, 15.0)); + mobility.SetPositionAllocator(allocator); + mobility.Install(gateways); + + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + /********************** + * Handle buildings * + **********************/ + + double xLength = 130; + double deltaX = 32; + double yLength = 64; + double deltaY = 17; + int gridWidth = 2 * radius / (xLength + deltaX); + int gridHeight = 2 * radius / (yLength + deltaY); + if (realisticChannelModel == false) { - gridWidth = 0; - gridHeight = 0; + gridWidth = 0; + gridHeight = 0; } - Ptr gridBuildingAllocator; - gridBuildingAllocator = CreateObject (); - gridBuildingAllocator->SetAttribute ("GridWidth", UintegerValue (gridWidth)); - gridBuildingAllocator->SetAttribute ("LengthX", DoubleValue (xLength)); - gridBuildingAllocator->SetAttribute ("LengthY", DoubleValue (yLength)); - gridBuildingAllocator->SetAttribute ("DeltaX", DoubleValue (deltaX)); - gridBuildingAllocator->SetAttribute ("DeltaY", DoubleValue (deltaY)); - gridBuildingAllocator->SetAttribute ("Height", DoubleValue (6)); - gridBuildingAllocator->SetBuildingAttribute ("NRoomsX", UintegerValue (2)); - gridBuildingAllocator->SetBuildingAttribute ("NRoomsY", UintegerValue (4)); - gridBuildingAllocator->SetBuildingAttribute ("NFloors", UintegerValue (2)); - gridBuildingAllocator->SetAttribute ( - "MinX", DoubleValue (-gridWidth * (xLength + deltaX) / 2 + deltaX / 2)); - gridBuildingAllocator->SetAttribute ( - "MinY", DoubleValue (-gridHeight * (yLength + deltaY) / 2 + deltaY / 2)); - BuildingContainer bContainer = gridBuildingAllocator->Create (gridWidth * gridHeight); - - BuildingsHelper::Install (endDevices); - BuildingsHelper::Install (gateways); - - // Print the buildings - if (print) + Ptr gridBuildingAllocator; + gridBuildingAllocator = CreateObject(); + gridBuildingAllocator->SetAttribute("GridWidth", UintegerValue(gridWidth)); + gridBuildingAllocator->SetAttribute("LengthX", DoubleValue(xLength)); + gridBuildingAllocator->SetAttribute("LengthY", DoubleValue(yLength)); + gridBuildingAllocator->SetAttribute("DeltaX", DoubleValue(deltaX)); + gridBuildingAllocator->SetAttribute("DeltaY", DoubleValue(deltaY)); + gridBuildingAllocator->SetAttribute("Height", DoubleValue(6)); + gridBuildingAllocator->SetBuildingAttribute("NRoomsX", UintegerValue(2)); + gridBuildingAllocator->SetBuildingAttribute("NRoomsY", UintegerValue(4)); + gridBuildingAllocator->SetBuildingAttribute("NFloors", UintegerValue(2)); + gridBuildingAllocator->SetAttribute( + "MinX", + DoubleValue(-gridWidth * (xLength + deltaX) / 2 + deltaX / 2)); + gridBuildingAllocator->SetAttribute( + "MinY", + DoubleValue(-gridHeight * (yLength + deltaY) / 2 + deltaY / 2)); + BuildingContainer bContainer = gridBuildingAllocator->Create(gridWidth * gridHeight); + + BuildingsHelper::Install(endDevices); + BuildingsHelper::Install(gateways); + + // Print the buildings + if (print) { - std::ofstream myfile; - myfile.open ("buildings.txt"); - std::vector>::const_iterator it; - int j = 1; - for (it = bContainer.Begin (); it != bContainer.End (); ++it, ++j) + std::ofstream myfile; + myfile.open("buildings.txt"); + std::vector>::const_iterator it; + int j = 1; + for (it = bContainer.Begin(); it != bContainer.End(); ++it, ++j) { - Box boundaries = (*it)->GetBoundaries (); - myfile << "set object " << j << " rect from " << boundaries.xMin << "," << boundaries.yMin - << " to " << boundaries.xMax << "," << boundaries.yMax << std::endl; + Box boundaries = (*it)->GetBoundaries(); + myfile << "set object " << j << " rect from " << boundaries.xMin << "," + << boundaries.yMin << " to " << boundaries.xMax << "," << boundaries.yMax + << std::endl; } - myfile.close (); + myfile.close(); } - /********************************************** - * Set up the end device's spreading factor * - **********************************************/ + /********************************************** + * Set up the end device's spreading factor * + **********************************************/ - macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); + macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); - NS_LOG_DEBUG ("Completed configuration"); + NS_LOG_DEBUG("Completed configuration"); - /********************************************* - * Install applications on the end devices * - *********************************************/ + /********************************************* + * Install applications on the end devices * + *********************************************/ - Time appStopTime = Seconds (simulationTime); - PeriodicSenderHelper appHelper = PeriodicSenderHelper (); - appHelper.SetPeriod (Seconds (appPeriodSeconds)); - appHelper.SetPacketSize (23); - Ptr rv = CreateObjectWithAttributes ( - "Min", DoubleValue (0), "Max", DoubleValue (10)); - ApplicationContainer appContainer = appHelper.Install (endDevices); + Time appStopTime = Seconds(simulationTime); + PeriodicSenderHelper appHelper = PeriodicSenderHelper(); + appHelper.SetPeriod(Seconds(appPeriodSeconds)); + appHelper.SetPacketSize(23); + Ptr rv = + CreateObjectWithAttributes("Min", + DoubleValue(0), + "Max", + DoubleValue(10)); + ApplicationContainer appContainer = appHelper.Install(endDevices); - appContainer.Start (Seconds (0)); - appContainer.Stop (appStopTime); + appContainer.Start(Seconds(0)); + appContainer.Stop(appStopTime); - /************************** - * Create Network Server * - ***************************/ + /************************** + * Create Network Server * + ***************************/ - // Create the NS node - NodeContainer networkServer; - networkServer.Create (1); + // Create the NS node + NodeContainer networkServer; + networkServer.Create(1); - // Create a NS for the network - nsHelper.SetEndDevices (endDevices); - nsHelper.SetGateways (gateways); - nsHelper.Install (networkServer); + // Create a NS for the network + nsHelper.SetEndDevices(endDevices); + nsHelper.SetGateways(gateways); + nsHelper.Install(networkServer); - //Create a forwarder for each gateway - forHelper.Install (gateways); + // Create a forwarder for each gateway + forHelper.Install(gateways); - //////////////// - // Simulation // - //////////////// + //////////////// + // Simulation // + //////////////// - Simulator::Stop (appStopTime + Hours (1)); + Simulator::Stop(appStopTime + Hours(1)); - NS_LOG_INFO ("Running simulation..."); - Simulator::Run (); + NS_LOG_INFO("Running simulation..."); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - /////////////////////////// - // Print results to file // - /////////////////////////// - NS_LOG_INFO ("Computing performance metrics..."); + /////////////////////////// + // Print results to file // + /////////////////////////// + NS_LOG_INFO("Computing performance metrics..."); - LoraPacketTracker &tracker = helper.GetPacketTracker (); - std::cout << tracker.CountMacPacketsGlobally (Seconds (0), appStopTime + Hours (1)) << std::endl; + LoraPacketTracker& tracker = helper.GetPacketTracker(); + std::cout << tracker.CountMacPacketsGlobally(Seconds(0), appStopTime + Hours(1)) << std::endl; - return 0; + return 0; } diff --git a/examples/frame-counter-update.cc b/examples/frame-counter-update.cc index 0aedd1ea68..c0a3567f28 100644 --- a/examples/frame-counter-update.cc +++ b/examples/frame-counter-update.cc @@ -4,263 +4,261 @@ * network. */ +#include "ns3/building-allocator.h" +#include "ns3/building-penetration-loss.h" +#include "ns3/buildings-helper.h" #include "ns3/callback.h" +#include "ns3/class-a-end-device-lorawan-mac.h" +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" +#include "ns3/correlated-shadowing-propagation-loss-model.h" +#include "ns3/double.h" #include "ns3/end-device-lora-phy.h" +#include "ns3/forwarder-helper.h" #include "ns3/gateway-lora-phy.h" -#include "ns3/class-a-end-device-lorawan-mac.h" #include "ns3/gateway-lorawan-mac.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/one-shot-sender-helper.h" -#include "ns3/simulator.h" #include "ns3/log.h" -#include "ns3/pointer.h" -#include "ns3/constant-position-mobility-model.h" #include "ns3/lora-helper.h" -#include "ns3/node-container.h" +#include "ns3/lorawan-mac-header.h" #include "ns3/mobility-helper.h" +#include "ns3/network-server-helper.h" +#include "ns3/node-container.h" +#include "ns3/one-shot-sender-helper.h" +#include "ns3/periodic-sender-helper.h" +#include "ns3/pointer.h" #include "ns3/position-allocator.h" -#include "ns3/double.h" #include "ns3/random-variable-stream.h" -#include "ns3/periodic-sender-helper.h" -#include "ns3/command-line.h" -#include "ns3/network-server-helper.h" -#include "ns3/correlated-shadowing-propagation-loss-model.h" -#include "ns3/building-penetration-loss.h" -#include "ns3/building-allocator.h" -#include "ns3/buildings-helper.h" -#include "ns3/forwarder-helper.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("FrameCounterUpdateExample"); +NS_LOG_COMPONENT_DEFINE("FrameCounterUpdateExample"); // Network settings int nGateways = 1; double simulationTime = 3600; void -OnPhySentPacket (Ptr packet, uint32_t index) +OnPhySentPacket(Ptr packet, uint32_t index) { - Ptr packetCopy = packet->Copy(); - - LorawanMacHeader mHdr; - packetCopy->RemoveHeader (mHdr); - LoraFrameHeader fHdr; - packetCopy->RemoveHeader (fHdr); - - NS_LOG_DEBUG ("Sent a packet with Frame Counter " << fHdr.GetFCnt()); - // NS_LOG_DEBUG ("MAC Header:"); - // NS_LOG_DEBUG (mHdr); - // NS_LOG_DEBUG ("Frame Header:"); - // NS_LOG_DEBUG (fHdr); + Ptr packetCopy = packet->Copy(); + + LorawanMacHeader mHdr; + packetCopy->RemoveHeader(mHdr); + LoraFrameHeader fHdr; + packetCopy->RemoveHeader(fHdr); + + NS_LOG_DEBUG("Sent a packet with Frame Counter " << fHdr.GetFCnt()); + // NS_LOG_DEBUG ("MAC Header:"); + // NS_LOG_DEBUG (mHdr); + // NS_LOG_DEBUG ("Frame Header:"); + // NS_LOG_DEBUG (fHdr); } void -OnMacPacketOutcome (uint8_t transmissions, bool successful, Time firstAttempt, Ptr packet) +OnMacPacketOutcome(uint8_t transmissions, bool successful, Time firstAttempt, Ptr packet) { - if (successful) - { - NS_LOG_INFO ("Packet was successful"); - } - else - { - NS_LOG_INFO ("Giving up"); - } + if (successful) + { + NS_LOG_INFO("Packet was successful"); + } + else + { + NS_LOG_INFO("Giving up"); + } } void -ChangeEndDevicePosition (Ptr endDevice, bool inRange) +ChangeEndDevicePosition(Ptr endDevice, bool inRange) { - if (inRange) + if (inRange) { - NS_LOG_INFO ("Moving ED in range"); - endDevice->GetObject ()->SetPosition (Vector(0.0, 0.0, 0.0)); + NS_LOG_INFO("Moving ED in range"); + endDevice->GetObject()->SetPosition(Vector(0.0, 0.0, 0.0)); } - else + else { - NS_LOG_INFO ("Moving ED out of range"); - endDevice->GetObject ()->SetPosition (Vector(10000.0, 0.0, 0.0)); + NS_LOG_INFO("Moving ED out of range"); + endDevice->GetObject()->SetPosition(Vector(10000.0, 0.0, 0.0)); } } int -main (int argc, char *argv[]) +main(int argc, char* argv[]) { + CommandLine cmd; + cmd.AddValue("simulationTime", "The time for which to simulate", simulationTime); + cmd.AddValue("MaxTransmissions", "ns3::EndDeviceLorawanMac::MaxTransmissions"); + cmd.AddValue("MType", "ns3::EndDeviceLorawanMac::MType"); + cmd.Parse(argc, argv); - CommandLine cmd; - cmd.AddValue ("simulationTime", "The time for which to simulate", simulationTime); - cmd.AddValue ("MaxTransmissions", - "ns3::EndDeviceLorawanMac::MaxTransmissions"); - cmd.AddValue ("MType", - "ns3::EndDeviceLorawanMac::MType"); - cmd.Parse (argc, argv); - - // Set up logging - LogComponentEnable ("FrameCounterUpdateExample", LOG_LEVEL_ALL); + // Set up logging + LogComponentEnable("FrameCounterUpdateExample", LOG_LEVEL_ALL); - /*********** - * Setup * - ***********/ + /*********** + * Setup * + ***********/ - // Mobility - MobilityHelper mobility; - Ptr allocator = CreateObject (); - // Make it so that nodes are at a certain height > 0 - allocator->Add (Vector (100000.0, 0.0, 15.0)); // ED position - allocator->Add (Vector (0.0, 0.0, 15.0)); // GW position - mobility.SetPositionAllocator (allocator); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + // Mobility + MobilityHelper mobility; + Ptr allocator = CreateObject(); + // Make it so that nodes are at a certain height > 0 + allocator->Add(Vector(100000.0, 0.0, 15.0)); // ED position + allocator->Add(Vector(0.0, 0.0, 15.0)); // GW position + mobility.SetPositionAllocator(allocator); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); - /************************ - * Create the channel * - ************************/ + /************************ + * Create the channel * + ************************/ - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); - Ptr delay = CreateObject (); + Ptr delay = CreateObject(); - Ptr channel = CreateObject (loss, delay); + Ptr channel = CreateObject(loss, delay); - /************************ - * Create the helpers * - ************************/ + /************************ + * Create the helpers * + ************************/ - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - helper.EnablePacketTracking (); // Output filename + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + helper.EnablePacketTracking(); // Output filename - //Create the NetworkServerHelper - NetworkServerHelper nsHelper = NetworkServerHelper (); + // Create the NetworkServerHelper + NetworkServerHelper nsHelper = NetworkServerHelper(); - //Create the ForwarderHelper - ForwarderHelper forHelper = ForwarderHelper (); + // Create the ForwarderHelper + ForwarderHelper forHelper = ForwarderHelper(); - /************************ - * Create End Devices * - ************************/ + /************************ + * Create End Devices * + ************************/ - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (1); + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(1); - // Assign a mobility model to each node - mobility.Install (endDevices); + // Assign a mobility model to each node + mobility.Install(endDevices); - // Make it so that nodes are at a certain height > 0 - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Make it so that nodes are at a certain height > 0 + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr mobility = (*j)->GetObject (); - Vector position = mobility->GetPosition (); - position.z = 1.2; - mobility->SetPosition (position); + Ptr mobility = (*j)->GetObject(); + Vector position = mobility->GetPosition(); + position.z = 1.2; + mobility->SetPosition(position); } - // Create the LoraNetDevices of the end devices - uint8_t nwkId = 54; - uint32_t nwkAddr = 1864; - Ptr addrGen = - CreateObject (nwkId, nwkAddr); - - // Create the LoraNetDevices of the end devices - macHelper.SetAddressGenerator (addrGen); - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - macHelper.Set("DataRate", UintegerValue(5)); - helper.Install (phyHelper, macHelper, endDevices); - - // Connect trace sources - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + // Create the LoraNetDevices of the end devices + uint8_t nwkId = 54; + uint32_t nwkAddr = 1864; + Ptr addrGen = + CreateObject(nwkId, nwkAddr); + + // Create the LoraNetDevices of the end devices + macHelper.SetAddressGenerator(addrGen); + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + macHelper.Set("DataRate", UintegerValue(5)); + helper.Install(phyHelper, macHelper, endDevices); + + // Connect trace sources + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr node = *j; - Ptr loraNetDevice = node->GetDevice (0)->GetObject (); - Ptr phy = loraNetDevice->GetPhy (); - Ptr mac = loraNetDevice->GetMac ()->GetObject (); - phy->TraceConnectWithoutContext("StartSending", MakeCallback(&OnPhySentPacket)); - mac->TraceConnectWithoutContext("RequiredTransmissions", MakeCallback(&OnMacPacketOutcome)); + Ptr node = *j; + Ptr loraNetDevice = node->GetDevice(0)->GetObject(); + Ptr phy = loraNetDevice->GetPhy(); + Ptr mac = loraNetDevice->GetMac()->GetObject(); + phy->TraceConnectWithoutContext("StartSending", MakeCallback(&OnPhySentPacket)); + mac->TraceConnectWithoutContext("RequiredTransmissions", MakeCallback(&OnMacPacketOutcome)); } - // Create the gateway nodes (allocate them uniformely on the disc) - NodeContainer gateways; - gateways.Create (nGateways); + // Create the gateway nodes (allocate them uniformely on the disc) + NodeContainer gateways; + gateways.Create(nGateways); - // Make it so that nodes are at a certain height > 0 - mobility.SetPositionAllocator (allocator); - mobility.Install (gateways); + // Make it so that nodes are at a certain height > 0 + mobility.SetPositionAllocator(allocator); + mobility.Install(gateways); - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); - NS_LOG_INFO ("Completed configuration"); + NS_LOG_INFO("Completed configuration"); - /********************************************* - * Install applications on the end devices * - *********************************************/ + /********************************************* + * Install applications on the end devices * + *********************************************/ - Time appStopTime = Seconds (simulationTime); - OneShotSenderHelper appHelper = OneShotSenderHelper (); - appHelper.SetSendTime (Seconds (0)); - ApplicationContainer appContainer = appHelper.Install (endDevices); - appHelper.SetSendTime (Seconds (100)); - appContainer.Add(appHelper.Install (endDevices)); - appHelper.SetSendTime (Seconds (200)); - appContainer.Add(appHelper.Install (endDevices)); + Time appStopTime = Seconds(simulationTime); + OneShotSenderHelper appHelper = OneShotSenderHelper(); + appHelper.SetSendTime(Seconds(0)); + ApplicationContainer appContainer = appHelper.Install(endDevices); + appHelper.SetSendTime(Seconds(100)); + appContainer.Add(appHelper.Install(endDevices)); + appHelper.SetSendTime(Seconds(200)); + appContainer.Add(appHelper.Install(endDevices)); - appContainer.Start (Seconds (0)); - appContainer.Stop (appStopTime); + appContainer.Start(Seconds(0)); + appContainer.Stop(appStopTime); - Simulator::Schedule (Seconds (110), &ChangeEndDevicePosition, endDevices.Get(0), true); - Simulator::Schedule (Seconds (201), &ChangeEndDevicePosition, endDevices.Get(0), false); - Simulator::Schedule (Seconds (204), &ChangeEndDevicePosition, endDevices.Get(0), true); + Simulator::Schedule(Seconds(110), &ChangeEndDevicePosition, endDevices.Get(0), true); + Simulator::Schedule(Seconds(201), &ChangeEndDevicePosition, endDevices.Get(0), false); + Simulator::Schedule(Seconds(204), &ChangeEndDevicePosition, endDevices.Get(0), true); - /************************** - * Create Network Server * - ***************************/ + /************************** + * Create Network Server * + ***************************/ - // Create the NS node - NodeContainer networkServer; - networkServer.Create (1); + // Create the NS node + NodeContainer networkServer; + networkServer.Create(1); - // Create a NS for the network - nsHelper.SetEndDevices (endDevices); - nsHelper.SetGateways (gateways); - nsHelper.Install (networkServer); + // Create a NS for the network + nsHelper.SetEndDevices(endDevices); + nsHelper.SetGateways(gateways); + nsHelper.Install(networkServer); - //Create a forwarder for each gateway - forHelper.Install (gateways); + // Create a forwarder for each gateway + forHelper.Install(gateways); - //////////////// - // Simulation // - //////////////// + //////////////// + // Simulation // + //////////////// - Simulator::Stop (appStopTime + Hours (1)); + Simulator::Stop(appStopTime + Hours(1)); - NS_LOG_INFO ("Running simulation..."); - Simulator::Run (); + NS_LOG_INFO("Running simulation..."); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - /////////////////////////// - // Print results to file // - /////////////////////////// + /////////////////////////// + // Print results to file // + /////////////////////////// - LoraPacketTracker &tracker = helper.GetPacketTracker (); - NS_LOG_INFO ("Printing total sent MAC-layer packets and successful MAC-layer packets"); - std::cout << tracker.CountMacPacketsGlobally (Seconds (0), appStopTime + Hours (1)) << std::endl; + LoraPacketTracker& tracker = helper.GetPacketTracker(); + NS_LOG_INFO("Printing total sent MAC-layer packets and successful MAC-layer packets"); + std::cout << tracker.CountMacPacketsGlobally(Seconds(0), appStopTime + Hours(1)) << std::endl; - return 0; + return 0; } diff --git a/examples/lorawan-energy-model-example.cc b/examples/lorawan-energy-model-example.cc index f6df665b5a..86b15ca625 100644 --- a/examples/lorawan-energy-model-example.cc +++ b/examples/lorawan-energy-model-example.cc @@ -3,191 +3,192 @@ * works. */ +#include "ns3/basic-energy-source-helper.h" +#include "ns3/class-a-end-device-lorawan-mac.h" +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" #include "ns3/end-device-lora-phy.h" +#include "ns3/file-helper.h" #include "ns3/gateway-lora-phy.h" -#include "ns3/class-a-end-device-lorawan-mac.h" #include "ns3/gateway-lorawan-mac.h" -#include "ns3/simulator.h" #include "ns3/log.h" -#include "ns3/constant-position-mobility-model.h" #include "ns3/lora-helper.h" +#include "ns3/lora-radio-energy-model-helper.h" #include "ns3/mobility-helper.h" +#include "ns3/names.h" #include "ns3/node-container.h" -#include "ns3/position-allocator.h" #include "ns3/periodic-sender-helper.h" -#include "ns3/command-line.h" -#include "ns3/basic-energy-source-helper.h" -#include "ns3/lora-radio-energy-model-helper.h" -#include "ns3/file-helper.h" -#include "ns3/names.h" +#include "ns3/position-allocator.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("LoraEnergyModelExample"); +NS_LOG_COMPONENT_DEFINE("LoraEnergyModelExample"); -int main (int argc, char *argv[]) +int +main(int argc, char* argv[]) { + // Set up logging + LogComponentEnable("LoraEnergyModelExample", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraRadioEnergyModel", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraChannel", LOG_LEVEL_INFO); + // LogComponentEnable ("LoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("GatewayLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraInterferenceHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LogicalLoraChannel", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraPhyHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMacHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSenderHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMacHeader", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraFrameHeader", LOG_LEVEL_ALL); + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + /************************ + * Create the channel * + ************************/ + + NS_LOG_INFO("Creating the channel..."); + + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr delay = CreateObject(); + + Ptr channel = CreateObject(loss, delay); + + /************************ + * Create the helpers * + ************************/ + + NS_LOG_INFO("Setting up helpers..."); + + MobilityHelper mobility; + Ptr allocator = CreateObject(); + allocator->Add(Vector(100, 0, 0)); + allocator->Add(Vector(0, 0, 0)); + mobility.SetPositionAllocator(allocator); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); + + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); - // Set up logging - LogComponentEnable ("LoraEnergyModelExample", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraRadioEnergyModel", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraChannel", LOG_LEVEL_INFO); - // LogComponentEnable ("LoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable ("GatewayLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraInterferenceHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LogicalLoraChannel", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraPhyHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMacHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSenderHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMacHeader", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraFrameHeader", LOG_LEVEL_ALL); - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - /************************ - * Create the channel * - ************************/ - - NS_LOG_INFO ("Creating the channel..."); - - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr delay = CreateObject (); - - Ptr channel = CreateObject (loss, delay); - - /************************ - * Create the helpers * - ************************/ - - NS_LOG_INFO ("Setting up helpers..."); - - MobilityHelper mobility; - Ptr allocator = CreateObject (); - allocator->Add (Vector (100,0,0)); - allocator->Add (Vector (0,0,0)); - mobility.SetPositionAllocator (allocator); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); - - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - - /************************ - * Create End Devices * - ************************/ + // Create the LoraHelper + LoraHelper helper = LoraHelper(); - NS_LOG_INFO ("Creating the end device..."); + /************************ + * Create End Devices * + ************************/ - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (1); + NS_LOG_INFO("Creating the end device..."); - // Assign a mobility model to the node - mobility.Install (endDevices); + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(1); - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - NetDeviceContainer endDevicesNetDevices = helper.Install (phyHelper, macHelper, endDevices); + // Assign a mobility model to the node + mobility.Install(endDevices); - /********************* - * Create Gateways * - *********************/ + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + NetDeviceContainer endDevicesNetDevices = helper.Install(phyHelper, macHelper, endDevices); - NS_LOG_INFO ("Creating the gateway..."); - NodeContainer gateways; - gateways.Create (1); + /********************* + * Create Gateways * + *********************/ - mobility.SetPositionAllocator (allocator); - mobility.Install (gateways); + NS_LOG_INFO("Creating the gateway..."); + NodeContainer gateways; + gateways.Create(1); - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); + mobility.SetPositionAllocator(allocator); + mobility.Install(gateways); - macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); - /********************************************* - * Install applications on the end devices * - *********************************************/ + macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); - // OneShotSenderHelper oneShotSenderHelper; - // oneShotSenderHelper.SetSendTime (Seconds (10)); + /********************************************* + * Install applications on the end devices * + *********************************************/ - // oneShotSenderHelper.Install (endDevices); + // OneShotSenderHelper oneShotSenderHelper; + // oneShotSenderHelper.SetSendTime (Seconds (10)); - PeriodicSenderHelper periodicSenderHelper; - periodicSenderHelper.SetPeriod (Seconds (5)); + // oneShotSenderHelper.Install (endDevices); - periodicSenderHelper.Install (endDevices); + PeriodicSenderHelper periodicSenderHelper; + periodicSenderHelper.SetPeriod(Seconds(5)); - /************************ - * Install Energy Model * - ************************/ + periodicSenderHelper.Install(endDevices); - BasicEnergySourceHelper basicSourceHelper; - LoraRadioEnergyModelHelper radioEnergyHelper; + /************************ + * Install Energy Model * + ************************/ - // configure energy source - basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (10000)); // Energy in J - basicSourceHelper.Set ("BasicEnergySupplyVoltageV", DoubleValue (3.3)); + BasicEnergySourceHelper basicSourceHelper; + LoraRadioEnergyModelHelper radioEnergyHelper; - radioEnergyHelper.Set ("StandbyCurrentA", DoubleValue (0.0014)); - radioEnergyHelper.Set ("TxCurrentA", DoubleValue (0.028)); - radioEnergyHelper.Set ("SleepCurrentA", DoubleValue (0.0000015)); - radioEnergyHelper.Set ("RxCurrentA", DoubleValue (0.0112)); + // configure energy source + basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ", DoubleValue(10000)); // Energy in J + basicSourceHelper.Set("BasicEnergySupplyVoltageV", DoubleValue(3.3)); - radioEnergyHelper.SetTxCurrentModel ("ns3::ConstantLoraTxCurrentModel", - "TxCurrent", DoubleValue (0.028)); + radioEnergyHelper.Set("StandbyCurrentA", DoubleValue(0.0014)); + radioEnergyHelper.Set("TxCurrentA", DoubleValue(0.028)); + radioEnergyHelper.Set("SleepCurrentA", DoubleValue(0.0000015)); + radioEnergyHelper.Set("RxCurrentA", DoubleValue(0.0112)); - // install source on EDs' nodes - EnergySourceContainer sources = basicSourceHelper.Install (endDevices); - Names::Add ("/Names/EnergySource", sources.Get (0)); + radioEnergyHelper.SetTxCurrentModel("ns3::ConstantLoraTxCurrentModel", + "TxCurrent", + DoubleValue(0.028)); - // install device model - DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install - (endDevicesNetDevices, sources); + // install source on EDs' nodes + EnergySourceContainer sources = basicSourceHelper.Install(endDevices); + Names::Add("/Names/EnergySource", sources.Get(0)); - /************** - * Get output * - **************/ - FileHelper fileHelper; - fileHelper.ConfigureFile ("battery-level", FileAggregator::SPACE_SEPARATED); - fileHelper.WriteProbe ("ns3::DoubleProbe", "/Names/EnergySource/RemainingEnergy", "Output"); + // install device model + DeviceEnergyModelContainer deviceModels = + radioEnergyHelper.Install(endDevicesNetDevices, sources); + /************** + * Get output * + **************/ + FileHelper fileHelper; + fileHelper.ConfigureFile("battery-level", FileAggregator::SPACE_SEPARATED); + fileHelper.WriteProbe("ns3::DoubleProbe", "/Names/EnergySource/RemainingEnergy", "Output"); - /**************** - * Simulation * - ****************/ + /**************** + * Simulation * + ****************/ - Simulator::Stop (Hours (24)); + Simulator::Stop(Hours(24)); - Simulator::Run (); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - return 0; + return 0; } diff --git a/examples/network-server-example.cc b/examples/network-server-example.cc index 09f43582b1..56a3469abd 100644 --- a/examples/network-server-example.cc +++ b/examples/network-server-example.cc @@ -4,178 +4,178 @@ * Two end devices are already configured to send unconfirmed and confirmed messages respectively. */ -#include "ns3/point-to-point-module.h" +#include "ns3/command-line.h" +#include "ns3/core-module.h" #include "ns3/forwarder-helper.h" -#include "ns3/network-server-helper.h" +#include "ns3/gateway-lora-phy.h" +#include "ns3/log.h" #include "ns3/lora-channel.h" -#include "ns3/mobility-helper.h" +#include "ns3/lora-device-address-generator.h" +#include "ns3/lora-helper.h" #include "ns3/lora-phy-helper.h" #include "ns3/lorawan-mac-helper.h" -#include "ns3/lora-helper.h" -#include "ns3/gateway-lora-phy.h" -#include "ns3/periodic-sender.h" -#include "ns3/periodic-sender-helper.h" -#include "ns3/log.h" -#include "ns3/string.h" -#include "ns3/command-line.h" -#include "ns3/core-module.h" +#include "ns3/mobility-helper.h" #include "ns3/network-module.h" -#include "ns3/lora-device-address-generator.h" +#include "ns3/network-server-helper.h" #include "ns3/one-shot-sender-helper.h" +#include "ns3/periodic-sender-helper.h" +#include "ns3/periodic-sender.h" +#include "ns3/point-to-point-module.h" +#include "ns3/string.h" using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("NetworkServerExample"); +NS_LOG_COMPONENT_DEFINE("NetworkServerExample"); -int main (int argc, char *argv[]) +int +main(int argc, char* argv[]) { - - bool verbose = false; - - CommandLine cmd; - cmd.AddValue ("verbose", "Whether to print output or not", verbose); - cmd.Parse (argc, argv); - - // Logging - ////////// - - LogComponentEnable ("NetworkServerExample", LOG_LEVEL_ALL); - LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL); - // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL); - // LogComponentEnable("MacCommand", LOG_LEVEL_ALL); - // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("LoraChannel", LOG_LEVEL_ALL); - // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); - // LogComponentEnable("PointToPointNetDevice", LOG_LEVEL_ALL); - // LogComponentEnable ("Forwarder", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); - // LogComponentEnable ("DeviceStatus", LOG_LEVEL_ALL); - // LogComponentEnable ("GatewayStatus", LOG_LEVEL_ALL); - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - // Create a simple wireless channel - /////////////////////////////////// - - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr delay = CreateObject (); - - Ptr channel = CreateObject (loss, delay); - - // Helpers - ////////// - - // End Device mobility - MobilityHelper mobilityEd, mobilityGw; - Ptr positionAllocEd = CreateObject (); - positionAllocEd->Add (Vector (6000.0, 0.0, 0.0)); - positionAllocEd->Add (Vector (0.0, 100.0, 0.0)); - mobilityEd.SetPositionAllocator (positionAllocEd); - mobilityEd.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Gateway mobility - Ptr positionAllocGw = CreateObject (); - positionAllocGw->Add (Vector (0.0, 0.0, 0.0)); - positionAllocGw->Add (Vector (-2000.0, 0.0, 0.0)); - positionAllocGw->Add (Vector (500.0, 0.0, 0.0)); - mobilityGw.SetPositionAllocator (positionAllocGw); - mobilityGw.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); - - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - - // Create EDs - ///////////// - - NodeContainer endDevices; - endDevices.Create (2); - mobilityEd.Install (endDevices); - - // Create a LoraDeviceAddressGenerator - uint8_t nwkId = 54; - uint32_t nwkAddr = 1864; - Ptr addrGen = CreateObject (nwkId,nwkAddr); - - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - macHelper.SetAddressGenerator (addrGen); - macHelper.SetRegion (LorawanMacHelper::EU); - helper.Install (phyHelper, macHelper, endDevices); - - // Set message type (Default is unconfirmed) - Ptr edMac1 = endDevices.Get (1)->GetDevice (0)->GetObject ()->GetMac (); - Ptr edLorawanMac1 = edMac1->GetObject (); - edLorawanMac1->SetMType (LorawanMacHeader::CONFIRMED_DATA_UP); - - - // Install applications in EDs - OneShotSenderHelper oneShotHelper = OneShotSenderHelper (); - oneShotHelper.SetSendTime (Seconds (4)); - oneShotHelper.Install (endDevices.Get (0)); - oneShotHelper.SetSendTime (Seconds (10)); - oneShotHelper.Install (endDevices.Get (1)); - // oneShotHelper.SetSendTime (Seconds (8)); - // oneShotHelper.Install(endDevices.Get (1)); - // oneShotHelper.SetSendTime (Seconds (12)); - // oneShotHelper.Install(endDevices.Get (2)); - - //////////////// - // Create GWs // - //////////////// - - NodeContainer gateways; - gateways.Create (1); - mobilityGw.Install (gateways); - - // Create the LoraNetDevices of the gateways - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - // Set spreading factors up - macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); - - //////////// - // Create NS - //////////// - - NodeContainer networkServers; - networkServers.Create (1); - - // Install the NetworkServer application on the network server - NetworkServerHelper networkServerHelper; - networkServerHelper.SetGateways (gateways); - networkServerHelper.SetEndDevices (endDevices); - networkServerHelper.Install (networkServers); - - // Install the Forwarder application on the gateways - ForwarderHelper forwarderHelper; - forwarderHelper.Install (gateways); - - // Start simulation - Simulator::Stop (Seconds (800)); - Simulator::Run (); - Simulator::Destroy (); - - return 0; + bool verbose = false; + + CommandLine cmd; + cmd.AddValue("verbose", "Whether to print output or not", verbose); + cmd.Parse(argc, argv); + + // Logging + ////////// + + LogComponentEnable("NetworkServerExample", LOG_LEVEL_ALL); + LogComponentEnable("NetworkServer", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL); + // LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL); + // LogComponentEnable("MacCommand", LOG_LEVEL_ALL); + // LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("LoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("LoraChannel", LOG_LEVEL_ALL); + // LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); + // LogComponentEnable("PointToPointNetDevice", LOG_LEVEL_ALL); + // LogComponentEnable ("Forwarder", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); + // LogComponentEnable ("DeviceStatus", LOG_LEVEL_ALL); + // LogComponentEnable ("GatewayStatus", LOG_LEVEL_ALL); + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + // Create a simple wireless channel + /////////////////////////////////// + + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr delay = CreateObject(); + + Ptr channel = CreateObject(loss, delay); + + // Helpers + ////////// + + // End Device mobility + MobilityHelper mobilityEd, mobilityGw; + Ptr positionAllocEd = CreateObject(); + positionAllocEd->Add(Vector(6000.0, 0.0, 0.0)); + positionAllocEd->Add(Vector(0.0, 100.0, 0.0)); + mobilityEd.SetPositionAllocator(positionAllocEd); + mobilityEd.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Gateway mobility + Ptr positionAllocGw = CreateObject(); + positionAllocGw->Add(Vector(0.0, 0.0, 0.0)); + positionAllocGw->Add(Vector(-2000.0, 0.0, 0.0)); + positionAllocGw->Add(Vector(500.0, 0.0, 0.0)); + mobilityGw.SetPositionAllocator(positionAllocGw); + mobilityGw.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); + + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); + + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + + // Create EDs + ///////////// + + NodeContainer endDevices; + endDevices.Create(2); + mobilityEd.Install(endDevices); + + // Create a LoraDeviceAddressGenerator + uint8_t nwkId = 54; + uint32_t nwkAddr = 1864; + Ptr addrGen = + CreateObject(nwkId, nwkAddr); + + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + macHelper.SetAddressGenerator(addrGen); + macHelper.SetRegion(LorawanMacHelper::EU); + helper.Install(phyHelper, macHelper, endDevices); + + // Set message type (Default is unconfirmed) + Ptr edMac1 = endDevices.Get(1)->GetDevice(0)->GetObject()->GetMac(); + Ptr edLorawanMac1 = edMac1->GetObject(); + edLorawanMac1->SetMType(LorawanMacHeader::CONFIRMED_DATA_UP); + + // Install applications in EDs + OneShotSenderHelper oneShotHelper = OneShotSenderHelper(); + oneShotHelper.SetSendTime(Seconds(4)); + oneShotHelper.Install(endDevices.Get(0)); + oneShotHelper.SetSendTime(Seconds(10)); + oneShotHelper.Install(endDevices.Get(1)); + // oneShotHelper.SetSendTime (Seconds (8)); + // oneShotHelper.Install(endDevices.Get (1)); + // oneShotHelper.SetSendTime (Seconds (12)); + // oneShotHelper.Install(endDevices.Get (2)); + + //////////////// + // Create GWs // + //////////////// + + NodeContainer gateways; + gateways.Create(1); + mobilityGw.Install(gateways); + + // Create the LoraNetDevices of the gateways + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + // Set spreading factors up + macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); + + //////////// + // Create NS + //////////// + + NodeContainer networkServers; + networkServers.Create(1); + + // Install the NetworkServer application on the network server + NetworkServerHelper networkServerHelper; + networkServerHelper.SetGateways(gateways); + networkServerHelper.SetEndDevices(endDevices); + networkServerHelper.Install(networkServers); + + // Install the Forwarder application on the gateways + ForwarderHelper forwarderHelper; + forwarderHelper.Install(gateways); + + // Start simulation + Simulator::Stop(Seconds(800)); + Simulator::Run(); + Simulator::Destroy(); + + return 0; } diff --git a/examples/parallel-reception-example.cc b/examples/parallel-reception-example.cc index 026b7c36c4..d0a1b96d2f 100644 --- a/examples/parallel-reception-example.cc +++ b/examples/parallel-reception-example.cc @@ -3,159 +3,159 @@ * packet to the gateway. */ +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" #include "ns3/end-device-lora-phy.h" -#include "ns3/gateway-lora-phy.h" #include "ns3/end-device-lorawan-mac.h" +#include "ns3/gateway-lora-phy.h" #include "ns3/gateway-lorawan-mac.h" -#include "ns3/lorawan-mac-helper.h" -#include "ns3/simulator.h" #include "ns3/log.h" -#include "ns3/constant-position-mobility-model.h" #include "ns3/lora-helper.h" +#include "ns3/lorawan-mac-helper.h" #include "ns3/mobility-helper.h" #include "ns3/node-container.h" -#include "ns3/position-allocator.h" #include "ns3/one-shot-sender-helper.h" -#include "ns3/command-line.h" +#include "ns3/position-allocator.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("ParallelReceptionExample"); +NS_LOG_COMPONENT_DEFINE("ParallelReceptionExample"); int -main (int argc, char *argv[]) +main(int argc, char* argv[]) { - - // Set up logging - LogComponentEnable ("ParallelReceptionExample", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraChannel", LOG_LEVEL_INFO); - // LogComponentEnable ("LoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("SimpleGatewayLoraPhy", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraInterferenceHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); - // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LogicalLoraChannel", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraPhyHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMacHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSenderHelper", LOG_LEVEL_ALL); - // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); - // LogComponentEnable ("LorawanMacHeader", LOG_LEVEL_ALL); - // LogComponentEnable ("LoraFrameHeader", LOG_LEVEL_ALL); - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - /************************ - * Create the channel * - ************************/ - - NS_LOG_INFO ("Creating the channel..."); - - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr delay = CreateObject (); - - Ptr channel = CreateObject (loss, delay); - - /************************ - * Create the helpers * - ************************/ - - NS_LOG_INFO ("Setting up helpers..."); - - MobilityHelper mobility; - Ptr allocator = CreateObject (); - allocator->Add (Vector (0, 0, 0)); - mobility.SetPositionAllocator (allocator); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); - - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - - /************************ - * Create End Devices * - ************************/ - - NS_LOG_INFO ("Creating the end device..."); - - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (6); - - // Assign a mobility model to the nodes - mobility.Install (endDevices); - - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - macHelper.SetRegion (LorawanMacHelper::SingleChannel); - helper.Install (phyHelper, macHelper, endDevices); - - /********************* - * Create Gateways * - *********************/ - - NS_LOG_INFO ("Creating the gateway..."); - NodeContainer gateways; - gateways.Create (1); - - mobility.Install (gateways); - - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - /********************************************* - * Install applications on the end devices * - *********************************************/ - - OneShotSenderHelper oneShotSenderHelper; - - oneShotSenderHelper.SetSendTime (Seconds (1)); - oneShotSenderHelper.Install (endDevices); - - /****************** - * Set Data Rates * - ******************/ - for (uint32_t i = 0; i < endDevices.GetN (); i++) + // Set up logging + LogComponentEnable("ParallelReceptionExample", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraChannel", LOG_LEVEL_INFO); + // LogComponentEnable ("LoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("SimpleGatewayLoraPhy", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraInterferenceHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); + // LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LogicalLoraChannel", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraPhyHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMacHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSenderHelper", LOG_LEVEL_ALL); + // LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); + // LogComponentEnable ("LorawanMacHeader", LOG_LEVEL_ALL); + // LogComponentEnable ("LoraFrameHeader", LOG_LEVEL_ALL); + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + /************************ + * Create the channel * + ************************/ + + NS_LOG_INFO("Creating the channel..."); + + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr delay = CreateObject(); + + Ptr channel = CreateObject(loss, delay); + + /************************ + * Create the helpers * + ************************/ + + NS_LOG_INFO("Setting up helpers..."); + + MobilityHelper mobility; + Ptr allocator = CreateObject(); + allocator->Add(Vector(0, 0, 0)); + mobility.SetPositionAllocator(allocator); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); + + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); + + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + + /************************ + * Create End Devices * + ************************/ + + NS_LOG_INFO("Creating the end device..."); + + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(6); + + // Assign a mobility model to the nodes + mobility.Install(endDevices); + + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + macHelper.SetRegion(LorawanMacHelper::SingleChannel); + helper.Install(phyHelper, macHelper, endDevices); + + /********************* + * Create Gateways * + *********************/ + + NS_LOG_INFO("Creating the gateway..."); + NodeContainer gateways; + gateways.Create(1); + + mobility.Install(gateways); + + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + /********************************************* + * Install applications on the end devices * + *********************************************/ + + OneShotSenderHelper oneShotSenderHelper; + + oneShotSenderHelper.SetSendTime(Seconds(1)); + oneShotSenderHelper.Install(endDevices); + + /****************** + * Set Data Rates * + ******************/ + for (uint32_t i = 0; i < endDevices.GetN(); i++) { - endDevices.Get (i) - ->GetDevice (0) - ->GetObject () - ->GetMac () - ->GetObject () - ->SetDataRate (5 - i); + endDevices.Get(i) + ->GetDevice(0) + ->GetObject() + ->GetMac() + ->GetObject() + ->SetDataRate(5 - i); } - /**************** - * Simulation * - ****************/ + /**************** + * Simulation * + ****************/ - Simulator::Stop (Hours (2)); + Simulator::Stop(Hours(2)); - Simulator::Run (); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - return 0; + return 0; } diff --git a/examples/simple-network-example.cc b/examples/simple-network-example.cc index 050176fcfd..2d9488e061 100644 --- a/examples/simple-network-example.cc +++ b/examples/simple-network-example.cc @@ -3,149 +3,150 @@ * packet to the gateway. */ +#include "ns3/command-line.h" +#include "ns3/constant-position-mobility-model.h" #include "ns3/end-device-lora-phy.h" -#include "ns3/gateway-lora-phy.h" #include "ns3/end-device-lorawan-mac.h" +#include "ns3/gateway-lora-phy.h" #include "ns3/gateway-lorawan-mac.h" -#include "ns3/simulator.h" #include "ns3/log.h" -#include "ns3/constant-position-mobility-model.h" #include "ns3/lora-helper.h" #include "ns3/mobility-helper.h" #include "ns3/node-container.h" -#include "ns3/position-allocator.h" #include "ns3/one-shot-sender-helper.h" -#include "ns3/command-line.h" +#include "ns3/position-allocator.h" +#include "ns3/simulator.h" + #include #include using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("SimpleLorawanNetworkExample"); +NS_LOG_COMPONENT_DEFINE("SimpleLorawanNetworkExample"); -int main (int argc, char *argv[]) +int +main(int argc, char* argv[]) { + // Set up logging + LogComponentEnable("SimpleLorawanNetworkExample", LOG_LEVEL_ALL); + LogComponentEnable("LoraChannel", LOG_LEVEL_INFO); + LogComponentEnable("LoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("LoraInterferenceHelper", LOG_LEVEL_ALL); + LogComponentEnable("LorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("LogicalLoraChannelHelper", LOG_LEVEL_ALL); + LogComponentEnable("LogicalLoraChannel", LOG_LEVEL_ALL); + LogComponentEnable("LoraHelper", LOG_LEVEL_ALL); + LogComponentEnable("LoraPhyHelper", LOG_LEVEL_ALL); + LogComponentEnable("LorawanMacHelper", LOG_LEVEL_ALL); + LogComponentEnable("OneShotSenderHelper", LOG_LEVEL_ALL); + LogComponentEnable("OneShotSender", LOG_LEVEL_ALL); + LogComponentEnable("LorawanMacHeader", LOG_LEVEL_ALL); + LogComponentEnable("LoraFrameHeader", LOG_LEVEL_ALL); + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + /************************ + * Create the channel * + ************************/ + + NS_LOG_INFO("Creating the channel..."); + + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr delay = CreateObject(); + + Ptr channel = CreateObject(loss, delay); + + /************************ + * Create the helpers * + ************************/ + + NS_LOG_INFO("Setting up helpers..."); + + MobilityHelper mobility; + Ptr allocator = CreateObject(); + allocator->Add(Vector(1000, 0, 0)); + allocator->Add(Vector(0, 0, 0)); + mobility.SetPositionAllocator(allocator); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); + + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); + + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); + + // Create the LoraHelper + LoraHelper helper = LoraHelper(); + + /************************ + * Create End Devices * + ************************/ + + NS_LOG_INFO("Creating the end device..."); + + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(1); + + // Assign a mobility model to the node + mobility.Install(endDevices); + + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + helper.Install(phyHelper, macHelper, endDevices); + + /********************* + * Create Gateways * + *********************/ + + NS_LOG_INFO("Creating the gateway..."); + NodeContainer gateways; + gateways.Create(1); + + mobility.Install(gateways); + + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); + + /********************************************* + * Install applications on the end devices * + *********************************************/ + + OneShotSenderHelper oneShotSenderHelper; + oneShotSenderHelper.SetSendTime(Seconds(2)); + + oneShotSenderHelper.Install(endDevices); - // Set up logging - LogComponentEnable ("SimpleLorawanNetworkExample", LOG_LEVEL_ALL); - LogComponentEnable ("LoraChannel", LOG_LEVEL_INFO); - LogComponentEnable ("LoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("LoraInterferenceHelper", LOG_LEVEL_ALL); - LogComponentEnable ("LorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("ClassAEndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("LogicalLoraChannelHelper", LOG_LEVEL_ALL); - LogComponentEnable ("LogicalLoraChannel", LOG_LEVEL_ALL); - LogComponentEnable ("LoraHelper", LOG_LEVEL_ALL); - LogComponentEnable ("LoraPhyHelper", LOG_LEVEL_ALL); - LogComponentEnable ("LorawanMacHelper", LOG_LEVEL_ALL); - LogComponentEnable ("OneShotSenderHelper", LOG_LEVEL_ALL); - LogComponentEnable ("OneShotSender", LOG_LEVEL_ALL); - LogComponentEnable ("LorawanMacHeader", LOG_LEVEL_ALL); - LogComponentEnable ("LoraFrameHeader", LOG_LEVEL_ALL); - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - /************************ - * Create the channel * - ************************/ - - NS_LOG_INFO ("Creating the channel..."); - - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr delay = CreateObject (); - - Ptr channel = CreateObject (loss, delay); - - /************************ - * Create the helpers * - ************************/ - - NS_LOG_INFO ("Setting up helpers..."); - - MobilityHelper mobility; - Ptr allocator = CreateObject (); - allocator->Add (Vector (1000,0,0)); - allocator->Add (Vector (0,0,0)); - mobility.SetPositionAllocator (allocator); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); - - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); - - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); - - // Create the LoraHelper - LoraHelper helper = LoraHelper (); - - /************************ - * Create End Devices * - ************************/ - - NS_LOG_INFO ("Creating the end device..."); - - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (1); - - // Assign a mobility model to the node - mobility.Install (endDevices); - - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - helper.Install (phyHelper, macHelper, endDevices); - - /********************* - * Create Gateways * - *********************/ - - NS_LOG_INFO ("Creating the gateway..."); - NodeContainer gateways; - gateways.Create (1); - - mobility.Install (gateways); - - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); - - /********************************************* - * Install applications on the end devices * - *********************************************/ - - OneShotSenderHelper oneShotSenderHelper; - oneShotSenderHelper.SetSendTime (Seconds (2)); - - oneShotSenderHelper.Install (endDevices); - - /****************** - * Set Data Rates * - ******************/ - std::vector sfQuantity (6); - sfQuantity = macHelper.SetSpreadingFactorsUp (endDevices, gateways, channel); + /****************** + * Set Data Rates * + ******************/ + std::vector sfQuantity(6); + sfQuantity = macHelper.SetSpreadingFactorsUp(endDevices, gateways, channel); - /**************** - * Simulation * - ****************/ + /**************** + * Simulation * + ****************/ - Simulator::Stop (Hours (2)); + Simulator::Stop(Hours(2)); - Simulator::Run (); + Simulator::Run(); - Simulator::Destroy (); + Simulator::Destroy(); - return 0; + return 0; } diff --git a/helper/forwarder-helper.cc b/helper/forwarder-helper.cc index d1e541f11e..82d53dcfe6 100644 --- a/helper/forwarder-helper.cc +++ b/helper/forwarder-helper.cc @@ -18,93 +18,93 @@ * Author: Davide Magrin */ -#include "ns3/forwarder-helper.h" -#include "ns3/random-variable-stream.h" -#include "ns3/forwarder.h" +#include "forwarder-helper.h" + #include "ns3/double.h" +#include "ns3/forwarder.h" +#include "ns3/log.h" +#include "ns3/random-variable-stream.h" +#include "ns3/simulator.h" #include "ns3/string.h" #include "ns3/trace-source-accessor.h" -#include "ns3/simulator.h" -#include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("ForwarderHelper"); +NS_LOG_COMPONENT_DEFINE("ForwarderHelper"); -ForwarderHelper::ForwarderHelper () +ForwarderHelper::ForwarderHelper() { - m_factory.SetTypeId ("ns3::Forwarder"); + m_factory.SetTypeId("ns3::Forwarder"); } -ForwarderHelper::~ForwarderHelper () +ForwarderHelper::~ForwarderHelper() { } void -ForwarderHelper::SetAttribute (std::string name, const AttributeValue &value) +ForwarderHelper::SetAttribute(std::string name, const AttributeValue& value) { - m_factory.Set (name, value); + m_factory.Set(name, value); } ApplicationContainer -ForwarderHelper::Install (Ptr node) const +ForwarderHelper::Install(Ptr node) const { - return ApplicationContainer (InstallPriv (node)); + return ApplicationContainer(InstallPriv(node)); } ApplicationContainer -ForwarderHelper::Install (NodeContainer c) const +ForwarderHelper::Install(NodeContainer c) const { - ApplicationContainer apps; - for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + ApplicationContainer apps; + for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) { - apps.Add (InstallPriv (*i)); + apps.Add(InstallPriv(*i)); } - return apps; + return apps; } Ptr -ForwarderHelper::InstallPriv (Ptr node) const +ForwarderHelper::InstallPriv(Ptr node) const { - NS_LOG_FUNCTION (this << node); + NS_LOG_FUNCTION(this << node); - Ptr app = m_factory.Create (); + Ptr app = m_factory.Create(); - app->SetNode (node); - node->AddApplication (app); + app->SetNode(node); + node->AddApplication(app); - // Link the Forwarder to the NetDevices - for (uint32_t i = 0; i < node->GetNDevices (); i++) + // Link the Forwarder to the NetDevices + for (uint32_t i = 0; i < node->GetNDevices(); i++) { - Ptr currentNetDevice = node->GetDevice (i); - if (currentNetDevice->GetObject()) + Ptr currentNetDevice = node->GetDevice(i); + if (currentNetDevice->GetObject()) { - Ptr loraNetDevice = - currentNetDevice->GetObject (); - app->SetLoraNetDevice (loraNetDevice); - loraNetDevice->SetReceiveCallback (MakeCallback - (&Forwarder::ReceiveFromLora, app)); + Ptr loraNetDevice = currentNetDevice->GetObject(); + app->SetLoraNetDevice(loraNetDevice); + loraNetDevice->SetReceiveCallback(MakeCallback(&Forwarder::ReceiveFromLora, app)); } - else if (currentNetDevice->GetObject ()) + else if (currentNetDevice->GetObject()) { - Ptr pointToPointNetDevice = - currentNetDevice->GetObject (); + Ptr pointToPointNetDevice = + currentNetDevice->GetObject(); - app->SetPointToPointNetDevice (pointToPointNetDevice); + app->SetPointToPointNetDevice(pointToPointNetDevice); - pointToPointNetDevice->SetReceiveCallback (MakeCallback - (&Forwarder::ReceiveFromPointToPoint, - app)); + pointToPointNetDevice->SetReceiveCallback( + MakeCallback(&Forwarder::ReceiveFromPointToPoint, app)); } - else + else { - NS_LOG_ERROR ("Potential error: NetDevice is neither Lora nor PointToPoint"); + NS_LOG_ERROR("Potential error: NetDevice is neither Lora nor PointToPoint"); } } - return app; -} + return app; } +} // namespace lorawan } // namespace ns3 diff --git a/helper/forwarder-helper.h b/helper/forwarder-helper.h index 93fd4fafae..dbae2b6b07 100644 --- a/helper/forwarder-helper.h +++ b/helper/forwarder-helper.h @@ -21,18 +21,21 @@ #ifndef FORWARDER_HELPER_H #define FORWARDER_HELPER_H -#include "ns3/object-factory.h" #include "ns3/address.h" +#include "ns3/application-container.h" #include "ns3/attribute.h" +#include "ns3/forwarder.h" #include "ns3/net-device.h" #include "ns3/node-container.h" -#include "ns3/application-container.h" -#include "ns3/forwarder.h" +#include "ns3/object-factory.h" + #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class can be used to install Forwarder applications on a set of @@ -40,24 +43,24 @@ namespace lorawan { */ class ForwarderHelper { -public: - ForwarderHelper (); + public: + ForwarderHelper(); - ~ForwarderHelper (); + ~ForwarderHelper(); - void SetAttribute (std::string name, const AttributeValue &value); + void SetAttribute(std::string name, const AttributeValue& value); - ApplicationContainer Install (NodeContainer c) const; + ApplicationContainer Install(NodeContainer c) const; - ApplicationContainer Install (Ptr node) const; + ApplicationContainer Install(Ptr node) const; -private: - Ptr InstallPriv (Ptr node) const; + private: + Ptr InstallPriv(Ptr node) const; - ObjectFactory m_factory; + ObjectFactory m_factory; }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* FORWARDER_HELPER_H */ diff --git a/helper/lora-helper.cc b/helper/lora-helper.cc index b4dcc4bcf0..fe4a58ff69 100644 --- a/helper/lora-helper.cc +++ b/helper/lora-helper.cc @@ -18,331 +18,323 @@ * Author: Davide Magrin */ -#include "ns3/lora-helper.h" +#include "lora-helper.h" + #include "ns3/log.h" #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraHelper"); +NS_LOG_COMPONENT_DEFINE("LoraHelper"); - LoraHelper::LoraHelper () : - m_lastPhyPerformanceUpdate (Seconds (0)), - m_lastGlobalPerformanceUpdate (Seconds (0)) - { - } +LoraHelper::LoraHelper() + : m_lastPhyPerformanceUpdate(Seconds(0)), + m_lastGlobalPerformanceUpdate(Seconds(0)) +{ +} - LoraHelper::~LoraHelper () - { - } +LoraHelper::~LoraHelper() +{ +} - NetDeviceContainer - LoraHelper::Install ( const LoraPhyHelper &phyHelper, - const LorawanMacHelper &macHelper, - NodeContainer c) const - { - NS_LOG_FUNCTION_NOARGS (); +NetDeviceContainer +LoraHelper::Install(const LoraPhyHelper& phyHelper, + const LorawanMacHelper& macHelper, + NodeContainer c) const +{ + NS_LOG_FUNCTION_NOARGS(); NetDeviceContainer devices; // Go over the various nodes in which to install the NetDevice - for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) - { + for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) + { Ptr node = *i; // Create the LoraNetDevice - Ptr device = CreateObject (); + Ptr device = CreateObject(); // Create the PHY - Ptr phy = phyHelper.Create (node, device); - NS_ASSERT (phy); - device->SetPhy (phy); - NS_LOG_DEBUG ("Done creating the PHY"); + Ptr phy = phyHelper.Create(node, device); + NS_ASSERT(phy); + device->SetPhy(phy); + NS_LOG_DEBUG("Done creating the PHY"); // Connect Trace Sources if necessary if (m_packetTracker) - { - if (phyHelper.GetDeviceType () == - TypeId::LookupByName ("ns3::SimpleEndDeviceLoraPhy")) - { - phy->TraceConnectWithoutContext ("StartSending", - MakeCallback - (&LoraPacketTracker::TransmissionCallback, - m_packetTracker)); - } - else if (phyHelper.GetDeviceType () == - TypeId::LookupByName ("ns3::SimpleGatewayLoraPhy")) + { + if (phyHelper.GetDeviceType() == TypeId::LookupByName("ns3::SimpleEndDeviceLoraPhy")) + { + phy->TraceConnectWithoutContext( + "StartSending", + MakeCallback(&LoraPacketTracker::TransmissionCallback, m_packetTracker)); + } + else if (phyHelper.GetDeviceType() == TypeId::LookupByName("ns3::SimpleGatewayLoraPhy")) { - phy->TraceConnectWithoutContext ("StartSending", - MakeCallback - (&LoraPacketTracker::TransmissionCallback, - m_packetTracker)); - phy->TraceConnectWithoutContext ("ReceivedPacket", - MakeCallback - (&LoraPacketTracker::PacketReceptionCallback, - m_packetTracker)); - phy->TraceConnectWithoutContext ("LostPacketBecauseInterference", - MakeCallback - (&LoraPacketTracker::InterferenceCallback, - m_packetTracker)); - phy->TraceConnectWithoutContext ("LostPacketBecauseNoMoreReceivers", - MakeCallback - (&LoraPacketTracker::NoMoreReceiversCallback, - m_packetTracker)); - phy->TraceConnectWithoutContext ("LostPacketBecauseUnderSensitivity", - MakeCallback - (&LoraPacketTracker::UnderSensitivityCallback, - m_packetTracker)); - phy->TraceConnectWithoutContext ("NoReceptionBecauseTransmitting", - MakeCallback - (&LoraPacketTracker::LostBecauseTxCallback, - m_packetTracker)); + phy->TraceConnectWithoutContext( + "StartSending", + MakeCallback(&LoraPacketTracker::TransmissionCallback, m_packetTracker)); + phy->TraceConnectWithoutContext( + "ReceivedPacket", + MakeCallback(&LoraPacketTracker::PacketReceptionCallback, m_packetTracker)); + phy->TraceConnectWithoutContext( + "LostPacketBecauseInterference", + MakeCallback(&LoraPacketTracker::InterferenceCallback, m_packetTracker)); + phy->TraceConnectWithoutContext( + "LostPacketBecauseNoMoreReceivers", + MakeCallback(&LoraPacketTracker::NoMoreReceiversCallback, m_packetTracker)); + phy->TraceConnectWithoutContext( + "LostPacketBecauseUnderSensitivity", + MakeCallback(&LoraPacketTracker::UnderSensitivityCallback, m_packetTracker)); + phy->TraceConnectWithoutContext( + "NoReceptionBecauseTransmitting", + MakeCallback(&LoraPacketTracker::LostBecauseTxCallback, m_packetTracker)); } } - // Create the MAC - Ptr mac = macHelper.Create (node, device); - NS_ASSERT (mac); - mac->SetPhy (phy); - NS_LOG_DEBUG ("Done creating the MAC"); - device->SetMac (mac); + // Create the MAC + Ptr mac = macHelper.Create(node, device); + NS_ASSERT(mac); + mac->SetPhy(phy); + NS_LOG_DEBUG("Done creating the MAC"); + device->SetMac(mac); - if (m_packetTracker) + if (m_packetTracker) { - if (phyHelper.GetDeviceType () == - TypeId::LookupByName ("ns3::SimpleEndDeviceLoraPhy")) + if (phyHelper.GetDeviceType() == TypeId::LookupByName("ns3::SimpleEndDeviceLoraPhy")) { - mac->TraceConnectWithoutContext ("SentNewPacket", - MakeCallback - (&LoraPacketTracker::MacTransmissionCallback, - m_packetTracker)); - - mac->TraceConnectWithoutContext ("RequiredTransmissions", - MakeCallback - (&LoraPacketTracker::RequiredTransmissionsCallback, - m_packetTracker)); + mac->TraceConnectWithoutContext( + "SentNewPacket", + MakeCallback(&LoraPacketTracker::MacTransmissionCallback, m_packetTracker)); + + mac->TraceConnectWithoutContext( + "RequiredTransmissions", + MakeCallback(&LoraPacketTracker::RequiredTransmissionsCallback, + m_packetTracker)); } - else if (phyHelper.GetDeviceType () == - TypeId::LookupByName ("ns3::SimpleGatewayLoraPhy")) + else if (phyHelper.GetDeviceType() == TypeId::LookupByName("ns3::SimpleGatewayLoraPhy")) { - mac->TraceConnectWithoutContext ("SentNewPacket", - MakeCallback - (&LoraPacketTracker::MacTransmissionCallback, - m_packetTracker)); - - mac->TraceConnectWithoutContext ("ReceivedPacket", - MakeCallback - (&LoraPacketTracker::MacGwReceptionCallback, - m_packetTracker)); + mac->TraceConnectWithoutContext( + "SentNewPacket", + MakeCallback(&LoraPacketTracker::MacTransmissionCallback, m_packetTracker)); + + mac->TraceConnectWithoutContext( + "ReceivedPacket", + MakeCallback(&LoraPacketTracker::MacGwReceptionCallback, m_packetTracker)); } } - node->AddDevice (device); - devices.Add (device); - NS_LOG_DEBUG ("node=" << node << ", mob=" << node->GetObject ()->GetPosition ()); + node->AddDevice(device); + devices.Add(device); + NS_LOG_DEBUG("node=" << node + << ", mob=" << node->GetObject()->GetPosition()); } - return devices; + return devices; } NetDeviceContainer -LoraHelper::Install ( const LoraPhyHelper &phy, - const LorawanMacHelper &mac, - Ptr node) const +LoraHelper::Install(const LoraPhyHelper& phy, const LorawanMacHelper& mac, Ptr node) const { - return Install (phy, mac, NodeContainer (node)); + return Install(phy, mac, NodeContainer(node)); } void -LoraHelper::EnablePacketTracking () +LoraHelper::EnablePacketTracking() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Create the packet tracker - m_packetTracker = new LoraPacketTracker (); + // Create the packet tracker + m_packetTracker = new LoraPacketTracker(); } LoraPacketTracker& -LoraHelper::GetPacketTracker (void) +LoraHelper::GetPacketTracker(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return *m_packetTracker; + return *m_packetTracker; } void -LoraHelper::EnableSimulationTimePrinting (Time interval) +LoraHelper::EnableSimulationTimePrinting(Time interval) { - m_oldtime = std::time (0); - Simulator::Schedule (Seconds (0), &LoraHelper::DoPrintSimulationTime, this, - interval); + m_oldtime = std::time(0); + Simulator::Schedule(Seconds(0), &LoraHelper::DoPrintSimulationTime, this, interval); } void -LoraHelper::EnablePeriodicDeviceStatusPrinting (NodeContainer endDevices, - NodeContainer gateways, - std::string filename, - Time interval) +LoraHelper::EnablePeriodicDeviceStatusPrinting(NodeContainer endDevices, + NodeContainer gateways, + std::string filename, + Time interval) { - NS_LOG_FUNCTION (this); - - DoPrintDeviceStatus (endDevices, gateways, filename); - - // Schedule periodic printing - Simulator::Schedule (interval, - &LoraHelper::EnablePeriodicDeviceStatusPrinting, this, - endDevices, gateways, filename, interval); + NS_LOG_FUNCTION(this); + + DoPrintDeviceStatus(endDevices, gateways, filename); + + // Schedule periodic printing + Simulator::Schedule(interval, + &LoraHelper::EnablePeriodicDeviceStatusPrinting, + this, + endDevices, + gateways, + filename, + interval); } void -LoraHelper::DoPrintDeviceStatus (NodeContainer endDevices, NodeContainer gateways, - std::string filename) +LoraHelper::DoPrintDeviceStatus(NodeContainer endDevices, + NodeContainer gateways, + std::string filename) { - const char * c = filename.c_str (); - std::ofstream outputFile; - if (Simulator::Now () == Seconds (0)) + const char* c = filename.c_str(); + std::ofstream outputFile; + if (Simulator::Now() == Seconds(0)) { - // Delete contents of the file as it is opened - outputFile.open (c, std::ofstream::out | std::ofstream::trunc); + // Delete contents of the file as it is opened + outputFile.open(c, std::ofstream::out | std::ofstream::trunc); } - else + else { - // Only append to the file - outputFile.open (c, std::ofstream::out | std::ofstream::app); + // Only append to the file + outputFile.open(c, std::ofstream::out | std::ofstream::app); } - Time currentTime = Simulator::Now(); - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + Time currentTime = Simulator::Now(); + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr object = *j; - Ptr position = object->GetObject (); - NS_ASSERT (position); - Ptr netDevice = object->GetDevice (0); - Ptr loraNetDevice = netDevice->GetObject (); - NS_ASSERT (loraNetDevice); - Ptr mac = loraNetDevice->GetMac ()->GetObject (); - int dr = int(mac->GetDataRate ()); - double txPower = mac->GetTransmissionPower (); - Vector pos = position->GetPosition (); - outputFile << currentTime.GetSeconds () << " " - << object->GetId () << " " - << pos.x << " " << pos.y << " " << dr << " " - << unsigned(txPower) << std::endl; + Ptr object = *j; + Ptr position = object->GetObject(); + NS_ASSERT(position); + Ptr netDevice = object->GetDevice(0); + Ptr loraNetDevice = netDevice->GetObject(); + NS_ASSERT(loraNetDevice); + Ptr mac = + loraNetDevice->GetMac()->GetObject(); + int dr = int(mac->GetDataRate()); + double txPower = mac->GetTransmissionPower(); + Vector pos = position->GetPosition(); + outputFile << currentTime.GetSeconds() << " " << object->GetId() << " " << pos.x << " " + << pos.y << " " << dr << " " << unsigned(txPower) << std::endl; } - // for (NodeContainer::Iterator j = gateways.Begin (); j != gateways.End (); ++j) - // { - // Ptr object = *j; - // Ptr position = object->GetObject (); - // Vector pos = position->GetPosition (); - // outputFile << currentTime.GetSeconds () << " " - // << object->GetId () << " " - // << pos.x << " " << pos.y << " " << "-1 -1" << std::endl; - // } - outputFile.close (); + // for (NodeContainer::Iterator j = gateways.Begin (); j != gateways.End (); ++j) + // { + // Ptr object = *j; + // Ptr position = object->GetObject (); + // Vector pos = position->GetPosition (); + // outputFile << currentTime.GetSeconds () << " " + // << object->GetId () << " " + // << pos.x << " " << pos.y << " " << "-1 -1" << std::endl; + // } + outputFile.close(); } - void -LoraHelper::EnablePeriodicPhyPerformancePrinting (NodeContainer gateways, - std::string filename, - Time interval) +LoraHelper::EnablePeriodicPhyPerformancePrinting(NodeContainer gateways, + std::string filename, + Time interval) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - DoPrintPhyPerformance (gateways, filename); + DoPrintPhyPerformance(gateways, filename); - Simulator::Schedule (interval, - &LoraHelper::EnablePeriodicPhyPerformancePrinting, - this, - gateways, filename, interval); + Simulator::Schedule(interval, + &LoraHelper::EnablePeriodicPhyPerformancePrinting, + this, + gateways, + filename, + interval); } void -LoraHelper::DoPrintPhyPerformance (NodeContainer gateways, - std::string filename) +LoraHelper::DoPrintPhyPerformance(NodeContainer gateways, std::string filename) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - const char * c = filename.c_str (); - std::ofstream outputFile; - if (Simulator::Now () == Seconds (0)) + const char* c = filename.c_str(); + std::ofstream outputFile; + if (Simulator::Now() == Seconds(0)) { - // Delete contents of the file as it is opened - outputFile.open (c, std::ofstream::out | std::ofstream::trunc); + // Delete contents of the file as it is opened + outputFile.open(c, std::ofstream::out | std::ofstream::trunc); } - else + else { - // Only append to the file - outputFile.open (c, std::ofstream::out | std::ofstream::app); + // Only append to the file + outputFile.open(c, std::ofstream::out | std::ofstream::app); } - for (auto it = gateways.Begin (); it != gateways.End (); ++it) + for (auto it = gateways.Begin(); it != gateways.End(); ++it) { - int systemId = (*it)->GetId (); - outputFile << Simulator::Now ().GetSeconds () << " " << - std::to_string(systemId) << " " << - m_packetTracker->PrintPhyPacketsPerGw(m_lastPhyPerformanceUpdate, - Simulator::Now (), - systemId) << std::endl; + int systemId = (*it)->GetId(); + outputFile << Simulator::Now().GetSeconds() << " " << std::to_string(systemId) << " " + << m_packetTracker->PrintPhyPacketsPerGw(m_lastPhyPerformanceUpdate, + Simulator::Now(), + systemId) + << std::endl; } - m_lastPhyPerformanceUpdate = Simulator::Now (); + m_lastPhyPerformanceUpdate = Simulator::Now(); - outputFile.close(); + outputFile.close(); } void -LoraHelper::EnablePeriodicGlobalPerformancePrinting (std::string filename, - Time interval) +LoraHelper::EnablePeriodicGlobalPerformancePrinting(std::string filename, Time interval) { - NS_LOG_FUNCTION (this << filename << interval); + NS_LOG_FUNCTION(this << filename << interval); - DoPrintGlobalPerformance (filename); + DoPrintGlobalPerformance(filename); - Simulator::Schedule (interval, - &LoraHelper::EnablePeriodicGlobalPerformancePrinting, - this, - filename, interval); + Simulator::Schedule(interval, + &LoraHelper::EnablePeriodicGlobalPerformancePrinting, + this, + filename, + interval); } void -LoraHelper::DoPrintGlobalPerformance (std::string filename) +LoraHelper::DoPrintGlobalPerformance(std::string filename) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - const char * c = filename.c_str (); - std::ofstream outputFile; - if (Simulator::Now () == Seconds (0)) + const char* c = filename.c_str(); + std::ofstream outputFile; + if (Simulator::Now() == Seconds(0)) { - // Delete contents of the file as it is opened - outputFile.open (c, std::ofstream::out | std::ofstream::trunc); + // Delete contents of the file as it is opened + outputFile.open(c, std::ofstream::out | std::ofstream::trunc); } - else + else { - // Only append to the file - outputFile.open (c, std::ofstream::out | std::ofstream::app); + // Only append to the file + outputFile.open(c, std::ofstream::out | std::ofstream::app); } - outputFile << Simulator::Now ().GetSeconds () << " " << - m_packetTracker->CountMacPacketsGlobally (m_lastGlobalPerformanceUpdate, - Simulator::Now ()) << - std::endl; + outputFile << Simulator::Now().GetSeconds() << " " + << m_packetTracker->CountMacPacketsGlobally(m_lastGlobalPerformanceUpdate, + Simulator::Now()) + << std::endl; - m_lastGlobalPerformanceUpdate = Simulator::Now (); + m_lastGlobalPerformanceUpdate = Simulator::Now(); - outputFile.close(); + outputFile.close(); } void -LoraHelper::DoPrintSimulationTime (Time interval) +LoraHelper::DoPrintSimulationTime(Time interval) { - // NS_LOG_INFO ("Time: " << Simulator::Now().GetHours()); - std::cout << "Simulated time: " << Simulator::Now ().GetHours () << " hours" << std::endl; - std::cout << "Real time from last call: " << std::time (0) - m_oldtime << " seconds" << std::endl; - m_oldtime = std::time (0); - Simulator::Schedule (interval, &LoraHelper::DoPrintSimulationTime, this, interval); + // NS_LOG_INFO ("Time: " << Simulator::Now().GetHours()); + std::cout << "Simulated time: " << Simulator::Now().GetHours() << " hours" << std::endl; + std::cout << "Real time from last call: " << std::time(0) - m_oldtime << " seconds" + << std::endl; + m_oldtime = std::time(0); + Simulator::Schedule(interval, &LoraHelper::DoPrintSimulationTime, this, interval); } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/helper/lora-helper.h b/helper/lora-helper.h index 98403224c7..58e2d856b0 100644 --- a/helper/lora-helper.h +++ b/helper/lora-helper.h @@ -21,18 +21,21 @@ #ifndef LORA_HELPER_H #define LORA_HELPER_H -#include "ns3/lora-phy-helper.h" -#include "ns3/lorawan-mac-helper.h" -#include "ns3/node-container.h" +#include "lora-packet-tracker.h" +#include "lora-phy-helper.h" +#include "lorawan-mac-helper.h" + +#include "ns3/lora-net-device.h" #include "ns3/net-device-container.h" #include "ns3/net-device.h" -#include "ns3/lora-net-device.h" -#include "ns3/lora-packet-tracker.h" +#include "ns3/node-container.h" #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Helps to create LoraNetDevice objects @@ -42,99 +45,99 @@ namespace lorawan { */ class LoraHelper { -public: - virtual ~LoraHelper (); - - LoraHelper (); - - /** - * Install LoraNetDevices on a list of nodes - * - * \param phy the PHY helper to create PHY objects - * \param mac the MAC helper to create MAC objects - * \param c the set of nodes on which a lora device must be created - * \returns a device container which contains all the devices created by this - * method. - */ - virtual NetDeviceContainer Install (const LoraPhyHelper &phyHelper, - const LorawanMacHelper &macHelper, - NodeContainer c) const; - - /** - * Install LoraNetDevice on a single node - * - * \param phy the PHY helper to create PHY objects - * \param mac the MAC helper to create MAC objects - * \param node the node on which a lora device must be created - * \returns a device container which contains all the devices created by this - * method. - */ - virtual NetDeviceContainer Install (const LoraPhyHelper &phyHelper, - const LorawanMacHelper &macHelper, - Ptr node) const; - - /** - * Enable tracking of packets via trace sources. - * - * This method automatically connects to trace sources to computes relevant - * metrics. - */ - void EnablePacketTracking (void); - - /** - * Periodically prints the simulation time to the standard output. - */ - void EnableSimulationTimePrinting (Time interval); - - /** - * Periodically prints the status of devices in the network to a file. - */ - void EnablePeriodicDeviceStatusPrinting (NodeContainer endDevices, - NodeContainer gateways, - std::string filename, - Time interval); - - /** - * Periodically prints PHY-level performance at every gateway in the container. - */ - void EnablePeriodicPhyPerformancePrinting (NodeContainer gateways, - std::string filename, - Time interval); - - void DoPrintPhyPerformance (NodeContainer gateways, std::string filename); - - /** - * Periodically prints global performance. - */ - void EnablePeriodicGlobalPerformancePrinting (std::string filename, - Time interval); - - void DoPrintGlobalPerformance (std::string filename); - - LoraPacketTracker& GetPacketTracker (void); - - LoraPacketTracker* m_packetTracker = 0; - - time_t m_oldtime; - - /** - * Print a summary of the status of all devices in the network. - */ - void DoPrintDeviceStatus (NodeContainer endDevices, NodeContainer gateways, - std::string filename); - -private: - /** - * Actually print the simulation time and re-schedule execution of this - * function. - */ - void DoPrintSimulationTime (Time interval); - - Time m_lastPhyPerformanceUpdate; - Time m_lastGlobalPerformanceUpdate; + public: + virtual ~LoraHelper(); + + LoraHelper(); + + /** + * Install LoraNetDevices on a list of nodes + * + * \param phy the PHY helper to create PHY objects + * \param mac the MAC helper to create MAC objects + * \param c the set of nodes on which a lora device must be created + * \returns a device container which contains all the devices created by this + * method. + */ + virtual NetDeviceContainer Install(const LoraPhyHelper& phyHelper, + const LorawanMacHelper& macHelper, + NodeContainer c) const; + + /** + * Install LoraNetDevice on a single node + * + * \param phy the PHY helper to create PHY objects + * \param mac the MAC helper to create MAC objects + * \param node the node on which a lora device must be created + * \returns a device container which contains all the devices created by this + * method. + */ + virtual NetDeviceContainer Install(const LoraPhyHelper& phyHelper, + const LorawanMacHelper& macHelper, + Ptr node) const; + + /** + * Enable tracking of packets via trace sources. + * + * This method automatically connects to trace sources to computes relevant + * metrics. + */ + void EnablePacketTracking(void); + + /** + * Periodically prints the simulation time to the standard output. + */ + void EnableSimulationTimePrinting(Time interval); + + /** + * Periodically prints the status of devices in the network to a file. + */ + void EnablePeriodicDeviceStatusPrinting(NodeContainer endDevices, + NodeContainer gateways, + std::string filename, + Time interval); + + /** + * Periodically prints PHY-level performance at every gateway in the container. + */ + void EnablePeriodicPhyPerformancePrinting(NodeContainer gateways, + std::string filename, + Time interval); + + void DoPrintPhyPerformance(NodeContainer gateways, std::string filename); + + /** + * Periodically prints global performance. + */ + void EnablePeriodicGlobalPerformancePrinting(std::string filename, Time interval); + + void DoPrintGlobalPerformance(std::string filename); + + LoraPacketTracker& GetPacketTracker(void); + + LoraPacketTracker* m_packetTracker = 0; + + time_t m_oldtime; + + /** + * Print a summary of the status of all devices in the network. + */ + void DoPrintDeviceStatus(NodeContainer endDevices, + NodeContainer gateways, + std::string filename); + + private: + /** + * Actually print the simulation time and re-schedule execution of this + * function. + */ + void DoPrintSimulationTime(Time interval); + + Time m_lastPhyPerformanceUpdate; + Time m_lastGlobalPerformanceUpdate; }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_HELPER_H */ diff --git a/helper/lora-packet-tracker.cc b/helper/lora-packet-tracker.cc index 0116e53406..bbbd608dc4 100644 --- a/helper/lora-packet-tracker.cc +++ b/helper/lora-packet-tracker.cc @@ -19,24 +19,28 @@ */ #include "lora-packet-tracker.h" + #include "ns3/log.h" -#include "ns3/simulator.h" #include "ns3/lorawan-mac-header.h" -#include +#include "ns3/simulator.h" + #include +#include -namespace ns3 { -namespace lorawan { -NS_LOG_COMPONENT_DEFINE ("LoraPacketTracker"); +namespace ns3 +{ +namespace lorawan +{ +NS_LOG_COMPONENT_DEFINE("LoraPacketTracker"); -LoraPacketTracker::LoraPacketTracker () +LoraPacketTracker::LoraPacketTracker() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LoraPacketTracker::~LoraPacketTracker () +LoraPacketTracker::~LoraPacketTracker() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } ///////////////// @@ -44,63 +48,59 @@ LoraPacketTracker::~LoraPacketTracker () ///////////////// void -LoraPacketTracker::MacTransmissionCallback (Ptr packet) +LoraPacketTracker::MacTransmissionCallback(Ptr packet) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("A new packet was sent by the MAC layer"); + NS_LOG_INFO("A new packet was sent by the MAC layer"); - MacPacketStatus status; - status.packet = packet; - status.sendTime = Simulator::Now (); - status.senderId = Simulator::GetContext (); - status.receivedTime = Time::Max (); + MacPacketStatus status; + status.packet = packet; + status.sendTime = Simulator::Now(); + status.senderId = Simulator::GetContext(); + status.receivedTime = Time::Max(); - m_macPacketTracker.insert (std::pair, MacPacketStatus> - (packet, status)); + m_macPacketTracker.insert(std::pair, MacPacketStatus>(packet, status)); } } void -LoraPacketTracker::RequiredTransmissionsCallback (uint8_t reqTx, bool success, - Time firstAttempt, - Ptr packet) +LoraPacketTracker::RequiredTransmissionsCallback(uint8_t reqTx, + bool success, + Time firstAttempt, + Ptr packet) { - NS_LOG_INFO ("Finished retransmission attempts for a packet"); - NS_LOG_DEBUG ("Packet: " << packet << "ReqTx " << unsigned(reqTx) << - ", succ: " << success << ", firstAttempt: " << - firstAttempt.GetSeconds ()); - - RetransmissionStatus entry; - entry.firstAttempt = firstAttempt; - entry.finishTime = Simulator::Now (); - entry.reTxAttempts = reqTx; - entry.successful = success; - - m_reTransmissionTracker.insert (std::pair, RetransmissionStatus> - (packet, entry)); + NS_LOG_INFO("Finished retransmission attempts for a packet"); + NS_LOG_DEBUG("Packet: " << packet << "ReqTx " << unsigned(reqTx) << ", succ: " << success + << ", firstAttempt: " << firstAttempt.GetSeconds()); + + RetransmissionStatus entry; + entry.firstAttempt = firstAttempt; + entry.finishTime = Simulator::Now(); + entry.reTxAttempts = reqTx; + entry.successful = success; + + m_reTransmissionTracker.insert(std::pair, RetransmissionStatus>(packet, entry)); } void -LoraPacketTracker::MacGwReceptionCallback (Ptr packet) +LoraPacketTracker::MacGwReceptionCallback(Ptr packet) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("A packet was successfully received" << - " at the MAC layer of gateway " << - Simulator::GetContext ()); + NS_LOG_INFO("A packet was successfully received" + << " at the MAC layer of gateway " << Simulator::GetContext()); - // Find the received packet in the m_macPacketTracker - auto it = m_macPacketTracker.find (packet); - if (it != m_macPacketTracker.end ()) + // Find the received packet in the m_macPacketTracker + auto it = m_macPacketTracker.find(packet); + if (it != m_macPacketTracker.end()) { - (*it).second.receptionTimes.insert (std::pair - (Simulator::GetContext (), - Simulator::Now ())); + (*it).second.receptionTimes.insert( + std::pair(Simulator::GetContext(), Simulator::Now())); } - else + else { - NS_ABORT_MSG ("Packet not found in tracker"); + NS_ABORT_MSG("Packet not found in tracker"); } } } @@ -110,107 +110,95 @@ LoraPacketTracker::MacGwReceptionCallback (Ptr packet) ///////////////// void -LoraPacketTracker::TransmissionCallback (Ptr packet, uint32_t edId) +LoraPacketTracker::TransmissionCallback(Ptr packet, uint32_t edId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("PHY packet " << packet - << " was transmitted by device " - << edId); - // Create a packetStatus - PacketStatus status; - status.packet = packet; - status.sendTime = Simulator::Now (); - status.senderId = edId; - - m_packetTracker.insert (std::pair, PacketStatus> (packet, status)); + NS_LOG_INFO("PHY packet " << packet << " was transmitted by device " << edId); + // Create a packetStatus + PacketStatus status; + status.packet = packet; + status.sendTime = Simulator::Now(); + status.senderId = edId; + + m_packetTracker.insert(std::pair, PacketStatus>(packet, status)); } } void -LoraPacketTracker::PacketReceptionCallback (Ptr packet, uint32_t gwId) +LoraPacketTracker::PacketReceptionCallback(Ptr packet, uint32_t gwId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - // Remove the successfully received packet from the list of sent ones - NS_LOG_INFO ("PHY packet " << packet - << " was successfully received at gateway " - << gwId); - - std::map, PacketStatus>::iterator it = m_packetTracker.find (packet); - (*it).second.outcomes.insert (std::pair (gwId, - RECEIVED)); + // Remove the successfully received packet from the list of sent ones + NS_LOG_INFO("PHY packet " << packet << " was successfully received at gateway " << gwId); + + std::map, PacketStatus>::iterator it = m_packetTracker.find(packet); + (*it).second.outcomes.insert(std::pair(gwId, RECEIVED)); } } void -LoraPacketTracker::InterferenceCallback (Ptr packet, uint32_t gwId) +LoraPacketTracker::InterferenceCallback(Ptr packet, uint32_t gwId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("PHY packet " << packet - << " was interfered at gateway " - << gwId); + NS_LOG_INFO("PHY packet " << packet << " was interfered at gateway " << gwId); - std::map, PacketStatus>::iterator it = m_packetTracker.find (packet); - (*it).second.outcomes.insert (std::pair (gwId, - INTERFERED)); + std::map, PacketStatus>::iterator it = m_packetTracker.find(packet); + (*it).second.outcomes.insert(std::pair(gwId, INTERFERED)); } } void -LoraPacketTracker::NoMoreReceiversCallback (Ptr packet, uint32_t gwId) +LoraPacketTracker::NoMoreReceiversCallback(Ptr packet, uint32_t gwId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("PHY packet " << packet - << " was lost because no more receivers at gateway " - << gwId); - std::map, PacketStatus>::iterator it = m_packetTracker.find (packet); - (*it).second.outcomes.insert (std::pair (gwId, - NO_MORE_RECEIVERS)); + NS_LOG_INFO("PHY packet " << packet << " was lost because no more receivers at gateway " + << gwId); + std::map, PacketStatus>::iterator it = m_packetTracker.find(packet); + (*it).second.outcomes.insert( + std::pair(gwId, NO_MORE_RECEIVERS)); } } void -LoraPacketTracker::UnderSensitivityCallback (Ptr packet, uint32_t gwId) +LoraPacketTracker::UnderSensitivityCallback(Ptr packet, uint32_t gwId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("PHY packet " << packet - << " was lost because under sensitivity at gateway " - << gwId); + NS_LOG_INFO("PHY packet " << packet << " was lost because under sensitivity at gateway " + << gwId); - std::map, PacketStatus>::iterator it = m_packetTracker.find (packet); - (*it).second.outcomes.insert (std::pair (gwId, - UNDER_SENSITIVITY)); + std::map, PacketStatus>::iterator it = m_packetTracker.find(packet); + (*it).second.outcomes.insert( + std::pair(gwId, UNDER_SENSITIVITY)); } } void -LoraPacketTracker::LostBecauseTxCallback (Ptr packet, uint32_t gwId) +LoraPacketTracker::LostBecauseTxCallback(Ptr packet, uint32_t gwId) { - if (IsUplink (packet)) + if (IsUplink(packet)) { - NS_LOG_INFO ("PHY packet " << packet - << " was lost because of GW transmission at gateway " - << gwId); + NS_LOG_INFO("PHY packet " << packet << " was lost because of GW transmission at gateway " + << gwId); - std::map, PacketStatus>::iterator it = m_packetTracker.find (packet); - (*it).second.outcomes.insert (std::pair (gwId, - LOST_BECAUSE_TX)); + std::map, PacketStatus>::iterator it = m_packetTracker.find(packet); + (*it).second.outcomes.insert(std::pair(gwId, LOST_BECAUSE_TX)); } } bool -LoraPacketTracker::IsUplink (Ptr packet) +LoraPacketTracker::IsUplink(Ptr packet) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - LorawanMacHeader mHdr; - Ptr copy = packet->Copy (); - copy->RemoveHeader (mHdr); - return mHdr.IsUplink (); + LorawanMacHeader mHdr; + Ptr copy = packet->Copy(); + copy->RemoveHeader(mHdr); + return mHdr.IsUplink(); } //////////////////////// @@ -218,188 +206,165 @@ LoraPacketTracker::IsUplink (Ptr packet) //////////////////////// std::vector -LoraPacketTracker::CountPhyPacketsPerGw (Time startTime, Time stopTime, - int gwId) +LoraPacketTracker::CountPhyPacketsPerGw(Time startTime, Time stopTime, int gwId) { - // Vector packetCounts will contain - for the interval given in the input of - // the function, the following fields: totPacketsSent receivedPackets - // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets + // Vector packetCounts will contain - for the interval given in the input of + // the function, the following fields: totPacketsSent receivedPackets + // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets - std::vector packetCounts (6, 0); + std::vector packetCounts(6, 0); - for (auto itPhy = m_packetTracker.begin (); - itPhy != m_packetTracker.end (); - ++itPhy) + for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy) { - if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime) + if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime) { - packetCounts.at (0)++; + packetCounts.at(0)++; - NS_LOG_DEBUG ("Dealing with packet " << (*itPhy).second.packet); - NS_LOG_DEBUG ("This packet was received by " << - (*itPhy).second.outcomes.size () << " gateways"); + NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet); + NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size() + << " gateways"); - if ((*itPhy).second.outcomes.count (gwId) > 0) + if ((*itPhy).second.outcomes.count(gwId) > 0) { - switch ((*itPhy).second.outcomes.at (gwId)) + switch ((*itPhy).second.outcomes.at(gwId)) { - case RECEIVED: - { - packetCounts.at (1)++; + case RECEIVED: { + packetCounts.at(1)++; break; - } - case INTERFERED: - { - packetCounts.at (2)++; + } + case INTERFERED: { + packetCounts.at(2)++; break; - } - case NO_MORE_RECEIVERS: - { - packetCounts.at (3)++; + } + case NO_MORE_RECEIVERS: { + packetCounts.at(3)++; break; - } - case UNDER_SENSITIVITY: - { - packetCounts.at (4)++; + } + case UNDER_SENSITIVITY: { + packetCounts.at(4)++; break; - } - case LOST_BECAUSE_TX: - { - packetCounts.at (5)++; + } + case LOST_BECAUSE_TX: { + packetCounts.at(5)++; break; - } - case UNSET: - { + } + case UNSET: { break; - } + } } } } } - return packetCounts; + return packetCounts; } + std::string -LoraPacketTracker::PrintPhyPacketsPerGw (Time startTime, Time stopTime, - int gwId) +LoraPacketTracker::PrintPhyPacketsPerGw(Time startTime, Time stopTime, int gwId) { - // Vector packetCounts will contain - for the interval given in the input of - // the function, the following fields: totPacketsSent receivedPackets - // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets + // Vector packetCounts will contain - for the interval given in the input of + // the function, the following fields: totPacketsSent receivedPackets + // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets - std::vector packetCounts (6, 0); + std::vector packetCounts(6, 0); - for (auto itPhy = m_packetTracker.begin (); - itPhy != m_packetTracker.end (); - ++itPhy) + for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy) { - if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime) + if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime) { - packetCounts.at (0)++; + packetCounts.at(0)++; - NS_LOG_DEBUG ("Dealing with packet " << (*itPhy).second.packet); - NS_LOG_DEBUG ("This packet was received by " << - (*itPhy).second.outcomes.size () << " gateways"); + NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet); + NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size() + << " gateways"); - if ((*itPhy).second.outcomes.count (gwId) > 0) + if ((*itPhy).second.outcomes.count(gwId) > 0) { - switch ((*itPhy).second.outcomes.at (gwId)) + switch ((*itPhy).second.outcomes.at(gwId)) { - case RECEIVED: - { - packetCounts.at (1)++; + case RECEIVED: { + packetCounts.at(1)++; break; - } - case INTERFERED: - { - packetCounts.at (2)++; + } + case INTERFERED: { + packetCounts.at(2)++; break; - } - case NO_MORE_RECEIVERS: - { - packetCounts.at (3)++; + } + case NO_MORE_RECEIVERS: { + packetCounts.at(3)++; break; - } - case UNDER_SENSITIVITY: - { - packetCounts.at (4)++; + } + case UNDER_SENSITIVITY: { + packetCounts.at(4)++; break; - } - case LOST_BECAUSE_TX: - { - packetCounts.at (5)++; + } + case LOST_BECAUSE_TX: { + packetCounts.at(5)++; break; - } - case UNSET: - { + } + case UNSET: { break; - } + } } } } } - std::string output (""); - for (int i = 0; i < 6; ++i) + std::string output(""); + for (int i = 0; i < 6; ++i) { - output += std::to_string (packetCounts.at (i)) + " "; + output += std::to_string(packetCounts.at(i)) + " "; } - return output; + return output; } - std::string - LoraPacketTracker::CountMacPacketsGlobally (Time startTime, Time stopTime) - { - NS_LOG_FUNCTION (this << startTime << stopTime); +std::string +LoraPacketTracker::CountMacPacketsGlobally(Time startTime, Time stopTime) +{ + NS_LOG_FUNCTION(this << startTime << stopTime); double sent = 0; double received = 0; - for (auto it = m_macPacketTracker.begin (); - it != m_macPacketTracker.end (); - ++it) - { + for (auto it = m_macPacketTracker.begin(); it != m_macPacketTracker.end(); ++it) + { if ((*it).second.sendTime >= startTime && (*it).second.sendTime <= stopTime) - { + { sent++; - if ((*it).second.receptionTimes.size ()) - { + if ((*it).second.receptionTimes.size()) + { received++; - } - } - } + } + } + } - return std::to_string (sent) + " " + - std::to_string (received); - } + return std::to_string(sent) + " " + std::to_string(received); +} - std::string - LoraPacketTracker::CountMacPacketsGloballyCpsr (Time startTime, Time stopTime) - { - NS_LOG_FUNCTION (this << startTime << stopTime); +std::string +LoraPacketTracker::CountMacPacketsGloballyCpsr(Time startTime, Time stopTime) +{ + NS_LOG_FUNCTION(this << startTime << stopTime); double sent = 0; double received = 0; - for (auto it = m_reTransmissionTracker.begin (); - it != m_reTransmissionTracker.end (); - ++it) - { + for (auto it = m_reTransmissionTracker.begin(); it != m_reTransmissionTracker.end(); ++it) + { if ((*it).second.firstAttempt >= startTime && (*it).second.firstAttempt <= stopTime) - { + { sent++; - NS_LOG_DEBUG ("Found a packet"); - NS_LOG_DEBUG ("Number of attempts: " << unsigned(it->second.reTxAttempts) << - ", successful: " << it->second.successful); + NS_LOG_DEBUG("Found a packet"); + NS_LOG_DEBUG("Number of attempts: " << unsigned(it->second.reTxAttempts) + << ", successful: " << it->second.successful); if (it->second.successful) - { + { received++; - } - } - } - - return std::to_string (sent) + " " + - std::to_string (received); - } + } + } + } + return std::to_string(sent) + " " + std::to_string(received); } -} + +} // namespace lorawan +} // namespace ns3 diff --git a/helper/lora-packet-tracker.h b/helper/lora-packet-tracker.h index ab8c3da450..e05d3e307f 100644 --- a/helper/lora-packet-tracker.h +++ b/helper/lora-packet-tracker.h @@ -21,149 +21,149 @@ #ifndef LORA_PACKET_TRACKER_H #define LORA_PACKET_TRACKER_H -#include "ns3/packet.h" #include "ns3/nstime.h" +#include "ns3/packet.h" #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ enum PhyPacketOutcome { - RECEIVED, - INTERFERED, - NO_MORE_RECEIVERS, - UNDER_SENSITIVITY, - LOST_BECAUSE_TX, - UNSET + RECEIVED, + INTERFERED, + NO_MORE_RECEIVERS, + UNDER_SENSITIVITY, + LOST_BECAUSE_TX, + UNSET }; struct PacketStatus { - Ptr packet; - uint32_t senderId; - Time sendTime; - std::map outcomes; + Ptr packet; + uint32_t senderId; + Time sendTime; + std::map outcomes; }; struct MacPacketStatus { - Ptr packet; - uint32_t senderId; - Time sendTime; - Time receivedTime; - std::map receptionTimes; + Ptr packet; + uint32_t senderId; + Time sendTime; + Time receivedTime; + std::map receptionTimes; }; struct RetransmissionStatus { - Time firstAttempt; - Time finishTime; - uint8_t reTxAttempts; - bool successful; + Time firstAttempt; + Time finishTime; + uint8_t reTxAttempts; + bool successful; }; -typedef std::map, MacPacketStatus> MacPacketData; -typedef std::map, PacketStatus> PhyPacketData; -typedef std::map, RetransmissionStatus> RetransmissionData; - +typedef std::map, MacPacketStatus> MacPacketData; +typedef std::map, PacketStatus> PhyPacketData; +typedef std::map, RetransmissionStatus> RetransmissionData; class LoraPacketTracker { -public: - LoraPacketTracker (); - ~LoraPacketTracker (); - - ///////////////////////// - // PHY layer callbacks // - ///////////////////////// - // Packet transmission callback - void TransmissionCallback (Ptr packet, uint32_t systemId); - // Packet outcome traces - void PacketReceptionCallback (Ptr packet, uint32_t systemId); - void InterferenceCallback (Ptr packet, uint32_t systemId); - void NoMoreReceiversCallback (Ptr packet, uint32_t systemId); - void UnderSensitivityCallback (Ptr packet, uint32_t systemId); - void LostBecauseTxCallback (Ptr packet, uint32_t systemId); - - ///////////////////////// - // MAC layer callbacks // - ///////////////////////// - // Packet transmission at an EndDevice - void MacTransmissionCallback (Ptr packet); - void RequiredTransmissionsCallback (uint8_t reqTx, bool success, - Time firstAttempt, Ptr packet); - // Packet reception at the Gateway - void MacGwReceptionCallback (Ptr packet); - - /////////////////////////////// - // Packet counting functions // - /////////////////////////////// - bool IsUplink (Ptr packet); - - // void CountRetransmissions (Time transient, Time simulationTime, MacPacketData - // macPacketTracker, RetransmissionData reTransmissionTracker, - // PhyPacketData packetTracker); - - /** - * Count packets to evaluate the performance at PHY level of a specific - * gateway. - */ - std::vector CountPhyPacketsPerGw (Time startTime, Time stopTime, - int systemId); - /** - * Count packets to evaluate the performance at PHY level of a specific - * gateway. - */ - std::string PrintPhyPacketsPerGw (Time startTime, Time stopTime, - int systemId); - /** - * Count packets to evaluate the performance at MAC level of a specific - * gateway. - */ - std::string CountMacPacketsPerGw (Time startTime, Time stopTime, - int systemId); - - /** - * Count packets to evaluate the performance at MAC level of a specific - * gateway. - */ - std::string PrintMacPacketsPerGw (Time startTime, Time stopTime, - int systemId); - - /** - * Count the number of retransmissions that were needed to correctly deliver a - * packet and receive the corresponding acknowledgment. - */ - std::string CountRetransmissions (Time startTime, Time stopTime); - - /** - * Count packets to evaluate the global performance at MAC level of the whole - * network. In this case, a MAC layer packet is labeled as successful if it - * was successful at at least one of the available gateways. - * - * This returns a string containing the number of sent packets and the number - * of packets that were received by at least one gateway. - */ - std::string CountMacPacketsGlobally (Time startTime, Time stopTime); - - /** - * Count packets to evaluate the global performance at MAC level of the whole - * network. In this case, a MAC layer packet is labeled as successful if it - * was successful at at least one of the available gateways, and if - * the corresponding acknowledgment was correctly delivered at the device. - * - * This returns a string containing the number of sent packets and the number - * of packets that generated a successful acknowledgment. - */ - std::string CountMacPacketsGloballyCpsr (Time startTime, Time stopTime); -private: - PhyPacketData m_packetTracker; - MacPacketData m_macPacketTracker; - RetransmissionData m_reTransmissionTracker; + public: + LoraPacketTracker(); + ~LoraPacketTracker(); + + ///////////////////////// + // PHY layer callbacks // + ///////////////////////// + // Packet transmission callback + void TransmissionCallback(Ptr packet, uint32_t systemId); + // Packet outcome traces + void PacketReceptionCallback(Ptr packet, uint32_t systemId); + void InterferenceCallback(Ptr packet, uint32_t systemId); + void NoMoreReceiversCallback(Ptr packet, uint32_t systemId); + void UnderSensitivityCallback(Ptr packet, uint32_t systemId); + void LostBecauseTxCallback(Ptr packet, uint32_t systemId); + + ///////////////////////// + // MAC layer callbacks // + ///////////////////////// + // Packet transmission at an EndDevice + void MacTransmissionCallback(Ptr packet); + void RequiredTransmissionsCallback(uint8_t reqTx, + bool success, + Time firstAttempt, + Ptr packet); + // Packet reception at the Gateway + void MacGwReceptionCallback(Ptr packet); + + /////////////////////////////// + // Packet counting functions // + /////////////////////////////// + bool IsUplink(Ptr packet); + + // void CountRetransmissions (Time transient, Time simulationTime, MacPacketData + // macPacketTracker, RetransmissionData reTransmissionTracker, + // PhyPacketData packetTracker); + + /** + * Count packets to evaluate the performance at PHY level of a specific + * gateway. + */ + std::vector CountPhyPacketsPerGw(Time startTime, Time stopTime, int systemId); + /** + * Count packets to evaluate the performance at PHY level of a specific + * gateway. + */ + std::string PrintPhyPacketsPerGw(Time startTime, Time stopTime, int systemId); + /** + * Count packets to evaluate the performance at MAC level of a specific + * gateway. + */ + std::string CountMacPacketsPerGw(Time startTime, Time stopTime, int systemId); + + /** + * Count packets to evaluate the performance at MAC level of a specific + * gateway. + */ + std::string PrintMacPacketsPerGw(Time startTime, Time stopTime, int systemId); + + /** + * Count the number of retransmissions that were needed to correctly deliver a + * packet and receive the corresponding acknowledgment. + */ + std::string CountRetransmissions(Time startTime, Time stopTime); + + /** + * Count packets to evaluate the global performance at MAC level of the whole + * network. In this case, a MAC layer packet is labeled as successful if it + * was successful at at least one of the available gateways. + * + * This returns a string containing the number of sent packets and the number + * of packets that were received by at least one gateway. + */ + std::string CountMacPacketsGlobally(Time startTime, Time stopTime); + + /** + * Count packets to evaluate the global performance at MAC level of the whole + * network. In this case, a MAC layer packet is labeled as successful if it + * was successful at at least one of the available gateways, and if + * the corresponding acknowledgment was correctly delivered at the device. + * + * This returns a string containing the number of sent packets and the number + * of packets that generated a successful acknowledgment. + */ + std::string CountMacPacketsGloballyCpsr(Time startTime, Time stopTime); + + private: + PhyPacketData m_packetTracker; + MacPacketData m_macPacketTracker; + RetransmissionData m_reTransmissionTracker; }; -} -} +} // namespace lorawan +} // namespace ns3 #endif diff --git a/helper/lora-phy-helper.cc b/helper/lora-phy-helper.cc index 060137be48..98e26e1aeb 100644 --- a/helper/lora-phy-helper.cc +++ b/helper/lora-phy-helper.cc @@ -18,125 +18,129 @@ * Author: Davide Magrin */ -#include "ns3/lora-phy-helper.h" +#include "lora-phy-helper.h" + #include "ns3/log.h" #include "ns3/sub-band.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraPhyHelper"); +NS_LOG_COMPONENT_DEFINE("LoraPhyHelper"); -LoraPhyHelper::LoraPhyHelper () : m_maxReceptionPaths (8), m_txPriority (true) +LoraPhyHelper::LoraPhyHelper() + : m_maxReceptionPaths(8), + m_txPriority(true) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -LoraPhyHelper::SetChannel (Ptr channel) +LoraPhyHelper::SetChannel(Ptr channel) { - m_channel = channel; + m_channel = channel; } void -LoraPhyHelper::SetDeviceType (enum DeviceType dt) +LoraPhyHelper::SetDeviceType(enum DeviceType dt) { - - NS_LOG_FUNCTION (this << dt); - switch (dt) + NS_LOG_FUNCTION(this << dt); + switch (dt) { case GW: - m_phy.SetTypeId ("ns3::SimpleGatewayLoraPhy"); - break; + m_phy.SetTypeId("ns3::SimpleGatewayLoraPhy"); + break; case ED: - m_phy.SetTypeId ("ns3::SimpleEndDeviceLoraPhy"); - break; + m_phy.SetTypeId("ns3::SimpleEndDeviceLoraPhy"); + break; } } TypeId -LoraPhyHelper::GetDeviceType (void) const +LoraPhyHelper::GetDeviceType(void) const { - NS_LOG_FUNCTION (this); - return m_phy.GetTypeId (); + NS_LOG_FUNCTION(this); + return m_phy.GetTypeId(); } void -LoraPhyHelper::Set (std::string name, const AttributeValue &v) +LoraPhyHelper::Set(std::string name, const AttributeValue& v) { - m_phy.Set (name, v); + m_phy.Set(name, v); } Ptr -LoraPhyHelper::Create (Ptr node, Ptr device) const +LoraPhyHelper::Create(Ptr node, Ptr device) const { - NS_LOG_FUNCTION (this << node->GetId () << device); + NS_LOG_FUNCTION(this << node->GetId() << device); - // Create the PHY and set its channel - Ptr phy = m_phy.Create (); - phy->SetChannel (m_channel); + // Create the PHY and set its channel + Ptr phy = m_phy.Create(); + phy->SetChannel(m_channel); - // Configuration is different based on the kind of device we have to create - std::string typeId = m_phy.GetTypeId ().GetName (); - if (typeId == "ns3::SimpleGatewayLoraPhy") + // Configuration is different based on the kind of device we have to create + std::string typeId = m_phy.GetTypeId().GetName(); + if (typeId == "ns3::SimpleGatewayLoraPhy") { - // Inform the channel of the presence of this PHY - m_channel->Add (phy); - - // For now, assume that the PHY will listen to the default EU channels - // with this ReceivePath configuration: - // 3 ReceivePaths on 868.1 - // 3 ReceivePaths on 868.3 - // 2 ReceivePaths on 868.5 - - // We expect that MacHelper instances will overwrite this setting if the - // device will operate in a different region - std::vector frequencies; - frequencies.push_back (868.1); - frequencies.push_back (868.3); - frequencies.push_back (868.5); - - for (auto &f : frequencies) + // Inform the channel of the presence of this PHY + m_channel->Add(phy); + + // For now, assume that the PHY will listen to the default EU channels + // with this ReceivePath configuration: + // 3 ReceivePaths on 868.1 + // 3 ReceivePaths on 868.3 + // 2 ReceivePaths on 868.5 + + // We expect that MacHelper instances will overwrite this setting if the + // device will operate in a different region + std::vector frequencies; + frequencies.push_back(868.1); + frequencies.push_back(868.3); + frequencies.push_back(868.5); + + for (auto& f : frequencies) { - phy->GetObject ()->AddFrequency (f); + phy->GetObject()->AddFrequency(f); } - int receptionPaths = 0; - // Set maxReceptionPaths as a parameter - // int maxReceptionPaths = 8; - while (receptionPaths < m_maxReceptionPaths) + int receptionPaths = 0; + // Set maxReceptionPaths as a parameter + // int maxReceptionPaths = 8; + while (receptionPaths < m_maxReceptionPaths) { - phy->GetObject ()->AddReceptionPath (); - receptionPaths++; + phy->GetObject()->AddReceptionPath(); + receptionPaths++; } } - else if (typeId == "ns3::SimpleEndDeviceLoraPhy") + else if (typeId == "ns3::SimpleEndDeviceLoraPhy") { - // The line below can be commented to speed up uplink-only simulations. - // This implies that the LoraChannel instance will only know about - // Gateways, and it will not lose time delivering packets and interference - // information to devices which will never listen. + // The line below can be commented to speed up uplink-only simulations. + // This implies that the LoraChannel instance will only know about + // Gateways, and it will not lose time delivering packets and interference + // information to devices which will never listen. - m_channel->Add (phy); + m_channel->Add(phy); } - // Link the PHY to its net device - phy->SetDevice (device); + // Link the PHY to its net device + phy->SetDevice(device); - return phy; + return phy; } void -LoraPhyHelper::SetMaxReceptionPaths (int maxReceptionPaths) +LoraPhyHelper::SetMaxReceptionPaths(int maxReceptionPaths) { - NS_LOG_FUNCTION (this << maxReceptionPaths); - m_maxReceptionPaths = maxReceptionPaths; + NS_LOG_FUNCTION(this << maxReceptionPaths); + m_maxReceptionPaths = maxReceptionPaths; } void -LoraPhyHelper::SetGatewayTransmissionPriority (bool txPriority) +LoraPhyHelper::SetGatewayTransmissionPriority(bool txPriority) { - m_txPriority = txPriority; + m_txPriority = txPriority; } } // namespace lorawan } // namespace ns3 diff --git a/helper/lora-phy-helper.h b/helper/lora-phy-helper.h index b5b51b1a07..b7eca6704f 100644 --- a/helper/lora-phy-helper.h +++ b/helper/lora-phy-helper.h @@ -21,113 +21,112 @@ #ifndef LORA_PHY_HELPER_H #define LORA_PHY_HELPER_H -#include "ns3/object-factory.h" -#include "ns3/net-device.h" #include "ns3/lora-channel.h" #include "ns3/lora-phy.h" +#include "ns3/lorawan-mac.h" +#include "ns3/net-device.h" +#include "ns3/object-factory.h" #include "ns3/simple-end-device-lora-phy.h" #include "ns3/simple-gateway-lora-phy.h" -#include "ns3/lorawan-mac.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Helper to install LoraPhy instances on multiple Nodes. */ class LoraPhyHelper { -public: - /** - * Enum for the type of device: End Device (ED) or Gateway (GW) - */ - enum DeviceType - { - GW, - ED - }; - - /** - * Create a phy helper without any parameter set. The user must set - * them all to be able to call Install later. - */ - LoraPhyHelper (); - - /** - * Set the LoraChannel to connect the PHYs to. - * - * Every PHY created by a call to Install is associated to this channel. - * - * \param channel the channel to associate to this helper. - */ - void SetChannel (Ptr channel); - - /** - * Set the kind of PHY this helper will create. - * - * \param dt the device type. - */ - void SetDeviceType (enum DeviceType dt); - - TypeId GetDeviceType (void) const; - - /** - * Set an attribute of the underlying PHY object. - * - * \param name the name of the attribute to set. - * \param v the value of the attribute. - */ - void Set (std::string name, const AttributeValue &v); - - /** - * Crate a LoraPhy and connect it to a device on a node. - * - * \param node the node on which we wish to create a wifi PHY. - * \param device the device within which this PHY will be created. - * \return a newly-created PHY object. - */ - Ptr Create (Ptr node, Ptr device) const; - - /** - * Set the maximum number of gateway receive paths - * - * \param maxReceptionPaths The maximum number of reception paths at - * the gateway - */ - void SetMaxReceptionPaths (int maxReceptionPaths); - - /** - * Set if giving priority to downlink transmission over reception at - * the gateways - */ - void SetGatewayTransmissionPriority (bool txPriority); - - - -private: - /** - * The PHY layer factory object. - */ - ObjectFactory m_phy; - - /** - * The channel instance the PHYs will be connected to. - */ - Ptr m_channel; - - /** - * The maximum number of receive paths at the gateway - */ - int m_maxReceptionPaths; - - /** - * If giving priority to downlink transmission over reception at the gateways - */ - bool m_txPriority; - + public: + /** + * Enum for the type of device: End Device (ED) or Gateway (GW) + */ + enum DeviceType + { + GW, + ED + }; + + /** + * Create a phy helper without any parameter set. The user must set + * them all to be able to call Install later. + */ + LoraPhyHelper(); + + /** + * Set the LoraChannel to connect the PHYs to. + * + * Every PHY created by a call to Install is associated to this channel. + * + * \param channel the channel to associate to this helper. + */ + void SetChannel(Ptr channel); + + /** + * Set the kind of PHY this helper will create. + * + * \param dt the device type. + */ + void SetDeviceType(enum DeviceType dt); + + TypeId GetDeviceType(void) const; + + /** + * Set an attribute of the underlying PHY object. + * + * \param name the name of the attribute to set. + * \param v the value of the attribute. + */ + void Set(std::string name, const AttributeValue& v); + + /** + * Crate a LoraPhy and connect it to a device on a node. + * + * \param node the node on which we wish to create a wifi PHY. + * \param device the device within which this PHY will be created. + * \return a newly-created PHY object. + */ + Ptr Create(Ptr node, Ptr device) const; + + /** + * Set the maximum number of gateway receive paths + * + * \param maxReceptionPaths The maximum number of reception paths at + * the gateway + */ + void SetMaxReceptionPaths(int maxReceptionPaths); + + /** + * Set if giving priority to downlink transmission over reception at + * the gateways + */ + void SetGatewayTransmissionPriority(bool txPriority); + + private: + /** + * The PHY layer factory object. + */ + ObjectFactory m_phy; + + /** + * The channel instance the PHYs will be connected to. + */ + Ptr m_channel; + + /** + * The maximum number of receive paths at the gateway + */ + int m_maxReceptionPaths; + + /** + * If giving priority to downlink transmission over reception at the gateways + */ + bool m_txPriority; }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_PHY_HELPER_H */ diff --git a/helper/lora-radio-energy-model-helper.cc b/helper/lora-radio-energy-model-helper.cc index 179dc5c164..12c979182a 100644 --- a/helper/lora-radio-energy-model-helper.cc +++ b/helper/lora-radio-energy-model-helper.cc @@ -18,91 +18,100 @@ */ #include "lora-radio-energy-model-helper.h" + +#include "ns3/end-device-lora-phy.h" #include "ns3/lora-net-device.h" #include "ns3/lora-tx-current-model.h" -#include "ns3/end-device-lora-phy.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -LoraRadioEnergyModelHelper::LoraRadioEnergyModelHelper () +LoraRadioEnergyModelHelper::LoraRadioEnergyModelHelper() { - m_radioEnergy.SetTypeId ("ns3::LoraRadioEnergyModel"); + m_radioEnergy.SetTypeId("ns3::LoraRadioEnergyModel"); } -LoraRadioEnergyModelHelper::~LoraRadioEnergyModelHelper () +LoraRadioEnergyModelHelper::~LoraRadioEnergyModelHelper() { } void -LoraRadioEnergyModelHelper::Set (std::string name, const AttributeValue &v) +LoraRadioEnergyModelHelper::Set(std::string name, const AttributeValue& v) { - m_radioEnergy.Set (name, v); + m_radioEnergy.Set(name, v); } void -LoraRadioEnergyModelHelper::SetTxCurrentModel (std::string name, - std::string n0, const AttributeValue& v0, - std::string n1, const AttributeValue& v1, - std::string n2, const AttributeValue& v2, - std::string n3, const AttributeValue& v3, - std::string n4, const AttributeValue& v4, - std::string n5, const AttributeValue& v5, - std::string n6, const AttributeValue& v6, - std::string n7, const AttributeValue& v7) +LoraRadioEnergyModelHelper::SetTxCurrentModel(std::string name, + std::string n0, + const AttributeValue& v0, + std::string n1, + const AttributeValue& v1, + std::string n2, + const AttributeValue& v2, + std::string n3, + const AttributeValue& v3, + std::string n4, + const AttributeValue& v4, + std::string n5, + const AttributeValue& v5, + std::string n6, + const AttributeValue& v6, + std::string n7, + const AttributeValue& v7) { - ObjectFactory factory; - factory.SetTypeId (name); - factory.Set (n0, v0); - factory.Set (n1, v1); - factory.Set (n2, v2); - factory.Set (n3, v3); - factory.Set (n4, v4); - factory.Set (n5, v5); - factory.Set (n6, v6); - factory.Set (n7, v7); - m_txCurrentModel = factory; + ObjectFactory factory; + factory.SetTypeId(name); + factory.Set(n0, v0); + factory.Set(n1, v1); + factory.Set(n2, v2); + factory.Set(n3, v3); + factory.Set(n4, v4); + factory.Set(n5, v5); + factory.Set(n6, v6); + factory.Set(n7, v7); + m_txCurrentModel = factory; } - /* * Private function starts here. */ Ptr -LoraRadioEnergyModelHelper::DoInstall (Ptr device, - Ptr source) const +LoraRadioEnergyModelHelper::DoInstall(Ptr device, Ptr source) const { - NS_ASSERT (device != NULL); - NS_ASSERT (source != NULL); - // check if device is LoraNetDevice - std::string deviceName = device->GetInstanceTypeId ().GetName (); - if (deviceName.compare ("ns3::LoraNetDevice") != 0) + NS_ASSERT(device != NULL); + NS_ASSERT(source != NULL); + // check if device is LoraNetDevice + std::string deviceName = device->GetInstanceTypeId().GetName(); + if (deviceName.compare("ns3::LoraNetDevice") != 0) { - NS_FATAL_ERROR ("NetDevice type is not LoraNetDevice!"); + NS_FATAL_ERROR("NetDevice type is not LoraNetDevice!"); } - Ptr node = device->GetNode (); - Ptr model = m_radioEnergy.Create ()->GetObject (); - NS_ASSERT (model != NULL); - // set energy source pointer - model->SetEnergySource (source); + Ptr node = device->GetNode(); + Ptr model = m_radioEnergy.Create()->GetObject(); + NS_ASSERT(model != NULL); + // set energy source pointer + model->SetEnergySource(source); - // set energy depletion callback - // if none is specified, make a callback to EndDeviceLoraPhy::SetSleepMode - Ptr loraDevice = device->GetObject (); - Ptr loraPhy = loraDevice->GetPhy ()->GetObject (); - // add model to device model list in energy source - source->AppendDeviceEnergyModel (model); - // create and register energy model phy listener - loraPhy->RegisterListener (model->GetPhyListener ()); + // set energy depletion callback + // if none is specified, make a callback to EndDeviceLoraPhy::SetSleepMode + Ptr loraDevice = device->GetObject(); + Ptr loraPhy = loraDevice->GetPhy()->GetObject(); + // add model to device model list in energy source + source->AppendDeviceEnergyModel(model); + // create and register energy model phy listener + loraPhy->RegisterListener(model->GetPhyListener()); - if (m_txCurrentModel.GetTypeId ().GetUid ()) + if (m_txCurrentModel.GetTypeId().GetUid()) { - Ptr txcurrent = m_txCurrentModel.Create (); - model->SetTxCurrentModel (txcurrent); + Ptr txcurrent = m_txCurrentModel.Create(); + model->SetTxCurrentModel(txcurrent); } - return model; + return model; } -} +} // namespace lorawan } // namespace ns3 diff --git a/helper/lora-radio-energy-model-helper.h b/helper/lora-radio-energy-model-helper.h index 133340563f..83be6c2731 100644 --- a/helper/lora-radio-energy-model-helper.h +++ b/helper/lora-radio-energy-model-helper.h @@ -1,21 +1,21 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation; -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* Author: Romagnolo Stefano -*/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Romagnolo Stefano + */ #ifndef LORA_RADIO_ENERGY_MODEL_HELPER_H #define LORA_RADIO_ENERGY_MODEL_HELPER_H @@ -23,8 +23,10 @@ #include "ns3/energy-model-helper.h" #include "ns3/lora-radio-energy-model.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * \ingroup energy @@ -35,74 +37,80 @@ namespace lorawan { */ class LoraRadioEnergyModelHelper : public DeviceEnergyModelHelper { -public: - /** - * Construct a helper which is used to add a radio energy model to a node - */ - LoraRadioEnergyModelHelper (); - - /** - * Destroy a RadioEnergy Helper - */ - ~LoraRadioEnergyModelHelper (); + public: + /** + * Construct a helper which is used to add a radio energy model to a node + */ + LoraRadioEnergyModelHelper(); - /** - * \param name the name of the attribute to set - * \param v the value of the attribute - * - * Sets an attribute of the underlying PHY object. - */ - void Set (std::string name, const AttributeValue &v); + /** + * Destroy a RadioEnergy Helper + */ + ~LoraRadioEnergyModelHelper(); - /** - * \param name the name of the model to set - * \param n0 the name of the attribute to set - * \param v0 the value of the attribute to set - * \param n1 the name of the attribute to set - * \param v1 the value of the attribute to set - * \param n2 the name of the attribute to set - * \param v2 the value of the attribute to set - * \param n3 the name of the attribute to set - * \param v3 the value of the attribute to set - * \param n4 the name of the attribute to set - * \param v4 the value of the attribute to set - * \param n5 the name of the attribute to set - * \param v5 the value of the attribute to set - * \param n6 the name of the attribute to set - * \param v6 the value of the attribute to set - * \param n7 the name of the attribute to set - * \param v7 the value of the attribute to set - * - * Configure a Transmission Current model for this EnergySource. - */ - void SetTxCurrentModel (std::string name, - std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (), - std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (), - std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (), - std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (), - std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (), - std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (), - std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (), - std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ()); + /** + * \param name the name of the attribute to set + * \param v the value of the attribute + * + * Sets an attribute of the underlying PHY object. + */ + void Set(std::string name, const AttributeValue& v); -private: - /** - * \param device Pointer to the NetDevice to install DeviceEnergyModel. - * \param source Pointer to EnergySource to install. - * \returns Ptr - * - * Implements DeviceEnergyModel::Install. - */ - virtual Ptr DoInstall (Ptr device, - Ptr source) const; + /** + * \param name the name of the model to set + * \param n0 the name of the attribute to set + * \param v0 the value of the attribute to set + * \param n1 the name of the attribute to set + * \param v1 the value of the attribute to set + * \param n2 the name of the attribute to set + * \param v2 the value of the attribute to set + * \param n3 the name of the attribute to set + * \param v3 the value of the attribute to set + * \param n4 the name of the attribute to set + * \param v4 the value of the attribute to set + * \param n5 the name of the attribute to set + * \param v5 the value of the attribute to set + * \param n6 the name of the attribute to set + * \param v6 the value of the attribute to set + * \param n7 the name of the attribute to set + * \param v7 the value of the attribute to set + * + * Configure a Transmission Current model for this EnergySource. + */ + void SetTxCurrentModel(std::string name, + std::string n0 = "", + const AttributeValue& v0 = EmptyAttributeValue(), + std::string n1 = "", + const AttributeValue& v1 = EmptyAttributeValue(), + std::string n2 = "", + const AttributeValue& v2 = EmptyAttributeValue(), + std::string n3 = "", + const AttributeValue& v3 = EmptyAttributeValue(), + std::string n4 = "", + const AttributeValue& v4 = EmptyAttributeValue(), + std::string n5 = "", + const AttributeValue& v5 = EmptyAttributeValue(), + std::string n6 = "", + const AttributeValue& v6 = EmptyAttributeValue(), + std::string n7 = "", + const AttributeValue& v7 = EmptyAttributeValue()); -private: - ObjectFactory m_radioEnergy; ///< radio energy - ObjectFactory m_txCurrentModel; ///< transmit current model + private: + /** + * \param device Pointer to the NetDevice to install DeviceEnergyModel. + * \param source Pointer to EnergySource to install. + * \returns Ptr + * + * Implements DeviceEnergyModel::Install. + */ + virtual Ptr DoInstall(Ptr device, Ptr source) const; + private: + ObjectFactory m_radioEnergy; ///< radio energy + ObjectFactory m_txCurrentModel; ///< transmit current model }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_RADIO_ENERGY_MODEL_HELPER_H */ diff --git a/helper/lorawan-mac-helper.cc b/helper/lorawan-mac-helper.cc index e70ba01640..74614b0244 100644 --- a/helper/lorawan-mac-helper.cc +++ b/helper/lorawan-mac-helper.cc @@ -18,653 +18,658 @@ * Author: Davide Magrin */ -#include "ns3/lorawan-mac-helper.h" -#include "ns3/gateway-lora-phy.h" +#include "lorawan-mac-helper.h" + #include "ns3/end-device-lora-phy.h" -#include "ns3/lora-net-device.h" +#include "ns3/gateway-lora-phy.h" #include "ns3/log.h" +#include "ns3/lora-net-device.h" #include "ns3/random-variable-stream.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LorawanMacHelper"); +NS_LOG_COMPONENT_DEFINE("LorawanMacHelper"); -LorawanMacHelper::LorawanMacHelper () : m_region (LorawanMacHelper::EU) +LorawanMacHelper::LorawanMacHelper() + : m_region(LorawanMacHelper::EU) { } void -LorawanMacHelper::Set (std::string name, const AttributeValue &v) +LorawanMacHelper::Set(std::string name, const AttributeValue& v) { - m_mac.Set (name, v); + m_mac.Set(name, v); } void -LorawanMacHelper::SetDeviceType (enum DeviceType dt) +LorawanMacHelper::SetDeviceType(enum DeviceType dt) { - NS_LOG_FUNCTION (this << dt); - switch (dt) + NS_LOG_FUNCTION(this << dt); + switch (dt) { case GW: - m_mac.SetTypeId ("ns3::GatewayLorawanMac"); - break; + m_mac.SetTypeId("ns3::GatewayLorawanMac"); + break; case ED_A: - m_mac.SetTypeId ("ns3::ClassAEndDeviceLorawanMac"); - break; + m_mac.SetTypeId("ns3::ClassAEndDeviceLorawanMac"); + break; } - m_deviceType = dt; + m_deviceType = dt; } void -LorawanMacHelper::SetAddressGenerator (Ptr addrGen) +LorawanMacHelper::SetAddressGenerator(Ptr addrGen) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_addrGen = addrGen; + m_addrGen = addrGen; } void -LorawanMacHelper::SetRegion (enum LorawanMacHelper::Regions region) +LorawanMacHelper::SetRegion(enum LorawanMacHelper::Regions region) { - m_region = region; + m_region = region; } Ptr -LorawanMacHelper::Create (Ptr node, Ptr device) const +LorawanMacHelper::Create(Ptr node, Ptr device) const { - Ptr mac = m_mac.Create (); - mac->SetDevice (device); + Ptr mac = m_mac.Create(); + mac->SetDevice(device); - // If we are operating on an end device, add an address to it - if (m_deviceType == ED_A && m_addrGen) + // If we are operating on an end device, add an address to it + if (m_deviceType == ED_A && m_addrGen) { - mac->GetObject ()->SetDeviceAddress (m_addrGen->NextAddress ()); + mac->GetObject()->SetDeviceAddress(m_addrGen->NextAddress()); } - // Add a basic list of channels based on the region where the device is - // operating - if (m_deviceType == ED_A) + // Add a basic list of channels based on the region where the device is + // operating + if (m_deviceType == ED_A) { - Ptr edMac = mac->GetObject (); - switch (m_region) + Ptr edMac = mac->GetObject(); + switch (m_region) { - case LorawanMacHelper::EU: { - ConfigureForEuRegion (edMac); + case LorawanMacHelper::EU: { + ConfigureForEuRegion(edMac); break; - } - case LorawanMacHelper::SingleChannel: { - ConfigureForSingleChannelRegion (edMac); + } + case LorawanMacHelper::SingleChannel: { + ConfigureForSingleChannelRegion(edMac); break; - } - case LorawanMacHelper::ALOHA: { - ConfigureForAlohaRegion (edMac); + } + case LorawanMacHelper::ALOHA: { + ConfigureForAlohaRegion(edMac); break; - } - default: { - NS_LOG_ERROR ("This region isn't supported yet!"); + } + default: { + NS_LOG_ERROR("This region isn't supported yet!"); break; - } + } } } - else + else { - Ptr gwMac = mac->GetObject (); - switch (m_region) + Ptr gwMac = mac->GetObject(); + switch (m_region) { - case LorawanMacHelper::EU: { - ConfigureForEuRegion (gwMac); + case LorawanMacHelper::EU: { + ConfigureForEuRegion(gwMac); break; - } - case LorawanMacHelper::SingleChannel: { - ConfigureForSingleChannelRegion (gwMac); + } + case LorawanMacHelper::SingleChannel: { + ConfigureForSingleChannelRegion(gwMac); break; - } - case LorawanMacHelper::ALOHA: { - ConfigureForAlohaRegion (gwMac); + } + case LorawanMacHelper::ALOHA: { + ConfigureForAlohaRegion(gwMac); break; - } - default: { - NS_LOG_ERROR ("This region isn't supported yet!"); + } + default: { + NS_LOG_ERROR("This region isn't supported yet!"); break; - } + } } } - return mac; + return mac; } void -LorawanMacHelper::ConfigureForAlohaRegion (Ptr edMac) const +LorawanMacHelper::ConfigureForAlohaRegion(Ptr edMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ApplyCommonAlohaConfigurations (edMac); - - ///////////////////////////////////////////////////// - // TxPower -> Transmission power in dBm conversion // - ///////////////////////////////////////////////////// - edMac->SetTxDbmForTxPower (std::vector{16, 14, 12, 10, 8, 6, 4, 2}); - - //////////////////////////////////////////////////////////// - // Matrix to know which DataRate the GW will respond with // - //////////////////////////////////////////////////////////// - LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, - {{1, 0, 0, 0, 0, 0}}, - {{2, 1, 0, 0, 0, 0}}, - {{3, 2, 1, 0, 0, 0}}, - {{4, 3, 2, 1, 0, 0}}, - {{5, 4, 3, 2, 1, 0}}, - {{6, 5, 4, 3, 2, 1}}, - {{7, 6, 5, 4, 3, 2}}}}; - edMac->SetReplyDataRateMatrix (matrix); - - ///////////////////// - // Preamble length // - ///////////////////// - edMac->SetNPreambleSymbols (8); - - ////////////////////////////////////// - // Second receive window parameters // - ////////////////////////////////////// - edMac->SetSecondReceiveWindowDataRate (0); - edMac->SetSecondReceiveWindowFrequency (869.525); + NS_LOG_FUNCTION_NOARGS(); + + ApplyCommonAlohaConfigurations(edMac); + + ///////////////////////////////////////////////////// + // TxPower -> Transmission power in dBm conversion // + ///////////////////////////////////////////////////// + edMac->SetTxDbmForTxPower(std::vector{16, 14, 12, 10, 8, 6, 4, 2}); + + //////////////////////////////////////////////////////////// + // Matrix to know which DataRate the GW will respond with // + //////////////////////////////////////////////////////////// + LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, + {{1, 0, 0, 0, 0, 0}}, + {{2, 1, 0, 0, 0, 0}}, + {{3, 2, 1, 0, 0, 0}}, + {{4, 3, 2, 1, 0, 0}}, + {{5, 4, 3, 2, 1, 0}}, + {{6, 5, 4, 3, 2, 1}}, + {{7, 6, 5, 4, 3, 2}}}}; + edMac->SetReplyDataRateMatrix(matrix); + + ///////////////////// + // Preamble length // + ///////////////////// + edMac->SetNPreambleSymbols(8); + + ////////////////////////////////////// + // Second receive window parameters // + ////////////////////////////////////// + edMac->SetSecondReceiveWindowDataRate(0); + edMac->SetSecondReceiveWindowFrequency(869.525); } void -LorawanMacHelper::ConfigureForAlohaRegion (Ptr gwMac) const +LorawanMacHelper::ConfigureForAlohaRegion(Ptr gwMac) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - /////////////////////////////// - // ReceivePath configuration // - /////////////////////////////// - Ptr gwPhy = - gwMac->GetDevice ()->GetObject ()->GetPhy ()->GetObject (); + /////////////////////////////// + // ReceivePath configuration // + /////////////////////////////// + Ptr gwPhy = + gwMac->GetDevice()->GetObject()->GetPhy()->GetObject(); - ApplyCommonAlohaConfigurations (gwMac); + ApplyCommonAlohaConfigurations(gwMac); - if (gwPhy) // If cast is successful, there's a GatewayLoraPhy + if (gwPhy) // If cast is successful, there's a GatewayLoraPhy { - NS_LOG_DEBUG ("Resetting reception paths"); - gwPhy->ResetReceptionPaths (); + NS_LOG_DEBUG("Resetting reception paths"); + gwPhy->ResetReceptionPaths(); - int receptionPaths = 0; - int maxReceptionPaths = 1; - while (receptionPaths < maxReceptionPaths) + int receptionPaths = 0; + int maxReceptionPaths = 1; + while (receptionPaths < maxReceptionPaths) { - gwPhy->GetObject ()->AddReceptionPath (); - receptionPaths++; + gwPhy->GetObject()->AddReceptionPath(); + receptionPaths++; } - gwPhy->AddFrequency (868.1); + gwPhy->AddFrequency(868.1); } } void -LorawanMacHelper::ApplyCommonAlohaConfigurations (Ptr lorawanMac) const +LorawanMacHelper::ApplyCommonAlohaConfigurations(Ptr lorawanMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ////////////// - // SubBands // - ////////////// - - LogicalLoraChannelHelper channelHelper; - channelHelper.AddSubBand (868, 868.6, 1, 14); - - ////////////////////// - // Default channels // - ////////////////////// - Ptr lc1 = CreateObject (868.1, 0, 5); - channelHelper.AddChannel (lc1); - - lorawanMac->SetLogicalLoraChannelHelper (channelHelper); - - /////////////////////////////////////////////// - // DataRate -> SF, DataRate -> Bandwidth // - // and DataRate -> MaxAppPayload conversions // - /////////////////////////////////////////////// - lorawanMac->SetSfForDataRate (std::vector{12, 11, 10, 9, 8, 7, 7}); - lorawanMac->SetBandwidthForDataRate ( - std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); - lorawanMac->SetMaxAppPayloadForDataRate ( - std::vector{59, 59, 59, 123, 230, 230, 230, 230}); + NS_LOG_FUNCTION_NOARGS(); + + ////////////// + // SubBands // + ////////////// + + LogicalLoraChannelHelper channelHelper; + channelHelper.AddSubBand(868, 868.6, 1, 14); + + ////////////////////// + // Default channels // + ////////////////////// + Ptr lc1 = CreateObject(868.1, 0, 5); + channelHelper.AddChannel(lc1); + + lorawanMac->SetLogicalLoraChannelHelper(channelHelper); + + /////////////////////////////////////////////// + // DataRate -> SF, DataRate -> Bandwidth // + // and DataRate -> MaxAppPayload conversions // + /////////////////////////////////////////////// + lorawanMac->SetSfForDataRate(std::vector{12, 11, 10, 9, 8, 7, 7}); + lorawanMac->SetBandwidthForDataRate( + std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); + lorawanMac->SetMaxAppPayloadForDataRate( + std::vector{59, 59, 59, 123, 230, 230, 230, 230}); } void -LorawanMacHelper::ConfigureForEuRegion (Ptr edMac) const +LorawanMacHelper::ConfigureForEuRegion(Ptr edMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ApplyCommonEuConfigurations (edMac); - - ///////////////////////////////////////////////////// - // TxPower -> Transmission power in dBm conversion // - ///////////////////////////////////////////////////// - edMac->SetTxDbmForTxPower (std::vector{16, 14, 12, 10, 8, 6, 4, 2}); - - //////////////////////////////////////////////////////////// - // Matrix to know which DataRate the GW will respond with // - //////////////////////////////////////////////////////////// - LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, - {{1, 0, 0, 0, 0, 0}}, - {{2, 1, 0, 0, 0, 0}}, - {{3, 2, 1, 0, 0, 0}}, - {{4, 3, 2, 1, 0, 0}}, - {{5, 4, 3, 2, 1, 0}}, - {{6, 5, 4, 3, 2, 1}}, - {{7, 6, 5, 4, 3, 2}}}}; - edMac->SetReplyDataRateMatrix (matrix); - - ///////////////////// - // Preamble length // - ///////////////////// - edMac->SetNPreambleSymbols (8); - - ////////////////////////////////////// - // Second receive window parameters // - ////////////////////////////////////// - edMac->SetSecondReceiveWindowDataRate (0); - edMac->SetSecondReceiveWindowFrequency (869.525); + NS_LOG_FUNCTION_NOARGS(); + + ApplyCommonEuConfigurations(edMac); + + ///////////////////////////////////////////////////// + // TxPower -> Transmission power in dBm conversion // + ///////////////////////////////////////////////////// + edMac->SetTxDbmForTxPower(std::vector{16, 14, 12, 10, 8, 6, 4, 2}); + + //////////////////////////////////////////////////////////// + // Matrix to know which DataRate the GW will respond with // + //////////////////////////////////////////////////////////// + LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, + {{1, 0, 0, 0, 0, 0}}, + {{2, 1, 0, 0, 0, 0}}, + {{3, 2, 1, 0, 0, 0}}, + {{4, 3, 2, 1, 0, 0}}, + {{5, 4, 3, 2, 1, 0}}, + {{6, 5, 4, 3, 2, 1}}, + {{7, 6, 5, 4, 3, 2}}}}; + edMac->SetReplyDataRateMatrix(matrix); + + ///////////////////// + // Preamble length // + ///////////////////// + edMac->SetNPreambleSymbols(8); + + ////////////////////////////////////// + // Second receive window parameters // + ////////////////////////////////////// + edMac->SetSecondReceiveWindowDataRate(0); + edMac->SetSecondReceiveWindowFrequency(869.525); } void -LorawanMacHelper::ConfigureForEuRegion (Ptr gwMac) const +LorawanMacHelper::ConfigureForEuRegion(Ptr gwMac) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - /////////////////////////////// - // ReceivePath configuration // - /////////////////////////////// - Ptr gwPhy = - gwMac->GetDevice ()->GetObject ()->GetPhy ()->GetObject (); + /////////////////////////////// + // ReceivePath configuration // + /////////////////////////////// + Ptr gwPhy = + gwMac->GetDevice()->GetObject()->GetPhy()->GetObject(); - ApplyCommonEuConfigurations (gwMac); + ApplyCommonEuConfigurations(gwMac); - if (gwPhy) // If cast is successful, there's a GatewayLoraPhy + if (gwPhy) // If cast is successful, there's a GatewayLoraPhy { - NS_LOG_DEBUG ("Resetting reception paths"); - gwPhy->ResetReceptionPaths (); + NS_LOG_DEBUG("Resetting reception paths"); + gwPhy->ResetReceptionPaths(); - std::vector frequencies; - frequencies.push_back (868.1); - frequencies.push_back (868.3); - frequencies.push_back (868.5); + std::vector frequencies; + frequencies.push_back(868.1); + frequencies.push_back(868.3); + frequencies.push_back(868.5); - for (auto &f : frequencies) + for (auto& f : frequencies) { - gwPhy->AddFrequency (f); + gwPhy->AddFrequency(f); } - int receptionPaths = 0; - int maxReceptionPaths = 8; - while (receptionPaths < maxReceptionPaths) + int receptionPaths = 0; + int maxReceptionPaths = 8; + while (receptionPaths < maxReceptionPaths) { - gwPhy->GetObject ()->AddReceptionPath (); - receptionPaths++; + gwPhy->GetObject()->AddReceptionPath(); + receptionPaths++; } } } void -LorawanMacHelper::ApplyCommonEuConfigurations (Ptr lorawanMac) const +LorawanMacHelper::ApplyCommonEuConfigurations(Ptr lorawanMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ////////////// - // SubBands // - ////////////// - - LogicalLoraChannelHelper channelHelper; - channelHelper.AddSubBand (868, 868.6, 0.01, 14); - channelHelper.AddSubBand (868.7, 869.2, 0.001, 14); - channelHelper.AddSubBand (869.4, 869.65, 0.1, 27); - - ////////////////////// - // Default channels // - ////////////////////// - Ptr lc1 = CreateObject (868.1, 0, 5); - Ptr lc2 = CreateObject (868.3, 0, 5); - Ptr lc3 = CreateObject (868.5, 0, 5); - channelHelper.AddChannel (lc1); - channelHelper.AddChannel (lc2); - channelHelper.AddChannel (lc3); - - lorawanMac->SetLogicalLoraChannelHelper (channelHelper); - - /////////////////////////////////////////////// - // DataRate -> SF, DataRate -> Bandwidth // - // and DataRate -> MaxAppPayload conversions // - /////////////////////////////////////////////// - lorawanMac->SetSfForDataRate (std::vector{12, 11, 10, 9, 8, 7, 7}); - lorawanMac->SetBandwidthForDataRate ( - std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); - lorawanMac->SetMaxAppPayloadForDataRate ( - std::vector{59, 59, 59, 123, 230, 230, 230, 230}); + NS_LOG_FUNCTION_NOARGS(); + + ////////////// + // SubBands // + ////////////// + + LogicalLoraChannelHelper channelHelper; + channelHelper.AddSubBand(868, 868.6, 0.01, 14); + channelHelper.AddSubBand(868.7, 869.2, 0.001, 14); + channelHelper.AddSubBand(869.4, 869.65, 0.1, 27); + + ////////////////////// + // Default channels // + ////////////////////// + Ptr lc1 = CreateObject(868.1, 0, 5); + Ptr lc2 = CreateObject(868.3, 0, 5); + Ptr lc3 = CreateObject(868.5, 0, 5); + channelHelper.AddChannel(lc1); + channelHelper.AddChannel(lc2); + channelHelper.AddChannel(lc3); + + lorawanMac->SetLogicalLoraChannelHelper(channelHelper); + + /////////////////////////////////////////////// + // DataRate -> SF, DataRate -> Bandwidth // + // and DataRate -> MaxAppPayload conversions // + /////////////////////////////////////////////// + lorawanMac->SetSfForDataRate(std::vector{12, 11, 10, 9, 8, 7, 7}); + lorawanMac->SetBandwidthForDataRate( + std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); + lorawanMac->SetMaxAppPayloadForDataRate( + std::vector{59, 59, 59, 123, 230, 230, 230, 230}); } /////////////////////////////// void -LorawanMacHelper::ConfigureForSingleChannelRegion (Ptr edMac) const +LorawanMacHelper::ConfigureForSingleChannelRegion(Ptr edMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ApplyCommonSingleChannelConfigurations (edMac); - - ///////////////////////////////////////////////////// - // TxPower -> Transmission power in dBm conversion // - ///////////////////////////////////////////////////// - edMac->SetTxDbmForTxPower (std::vector{16, 14, 12, 10, 8, 6, 4, 2}); - - //////////////////////////////////////////////////////////// - // Matrix to know which DataRate the GW will respond with // - //////////////////////////////////////////////////////////// - LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, - {{1, 0, 0, 0, 0, 0}}, - {{2, 1, 0, 0, 0, 0}}, - {{3, 2, 1, 0, 0, 0}}, - {{4, 3, 2, 1, 0, 0}}, - {{5, 4, 3, 2, 1, 0}}, - {{6, 5, 4, 3, 2, 1}}, - {{7, 6, 5, 4, 3, 2}}}}; - edMac->SetReplyDataRateMatrix (matrix); - - ///////////////////// - // Preamble length // - ///////////////////// - edMac->SetNPreambleSymbols (8); - - ////////////////////////////////////// - // Second receive window parameters // - ////////////////////////////////////// - edMac->SetSecondReceiveWindowDataRate (0); - edMac->SetSecondReceiveWindowFrequency (869.525); + NS_LOG_FUNCTION_NOARGS(); + + ApplyCommonSingleChannelConfigurations(edMac); + + ///////////////////////////////////////////////////// + // TxPower -> Transmission power in dBm conversion // + ///////////////////////////////////////////////////// + edMac->SetTxDbmForTxPower(std::vector{16, 14, 12, 10, 8, 6, 4, 2}); + + //////////////////////////////////////////////////////////// + // Matrix to know which DataRate the GW will respond with // + //////////////////////////////////////////////////////////// + LorawanMac::ReplyDataRateMatrix matrix = {{{{0, 0, 0, 0, 0, 0}}, + {{1, 0, 0, 0, 0, 0}}, + {{2, 1, 0, 0, 0, 0}}, + {{3, 2, 1, 0, 0, 0}}, + {{4, 3, 2, 1, 0, 0}}, + {{5, 4, 3, 2, 1, 0}}, + {{6, 5, 4, 3, 2, 1}}, + {{7, 6, 5, 4, 3, 2}}}}; + edMac->SetReplyDataRateMatrix(matrix); + + ///////////////////// + // Preamble length // + ///////////////////// + edMac->SetNPreambleSymbols(8); + + ////////////////////////////////////// + // Second receive window parameters // + ////////////////////////////////////// + edMac->SetSecondReceiveWindowDataRate(0); + edMac->SetSecondReceiveWindowFrequency(869.525); } void -LorawanMacHelper::ConfigureForSingleChannelRegion (Ptr gwMac) const +LorawanMacHelper::ConfigureForSingleChannelRegion(Ptr gwMac) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - /////////////////////////////// - // ReceivePath configuration // - /////////////////////////////// - Ptr gwPhy = - gwMac->GetDevice ()->GetObject ()->GetPhy ()->GetObject (); + /////////////////////////////// + // ReceivePath configuration // + /////////////////////////////// + Ptr gwPhy = + gwMac->GetDevice()->GetObject()->GetPhy()->GetObject(); - ApplyCommonEuConfigurations (gwMac); + ApplyCommonEuConfigurations(gwMac); - if (gwPhy) // If cast is successful, there's a GatewayLoraPhy + if (gwPhy) // If cast is successful, there's a GatewayLoraPhy { - NS_LOG_DEBUG ("Resetting reception paths"); - gwPhy->ResetReceptionPaths (); + NS_LOG_DEBUG("Resetting reception paths"); + gwPhy->ResetReceptionPaths(); - std::vector frequencies; - frequencies.push_back (868.1); + std::vector frequencies; + frequencies.push_back(868.1); - for (auto &f : frequencies) + for (auto& f : frequencies) { - gwPhy->AddFrequency (f); + gwPhy->AddFrequency(f); } - int receptionPaths = 0; - int maxReceptionPaths = 8; - while (receptionPaths < maxReceptionPaths) + int receptionPaths = 0; + int maxReceptionPaths = 8; + while (receptionPaths < maxReceptionPaths) { - gwPhy->GetObject ()->AddReceptionPath (); - receptionPaths++; + gwPhy->GetObject()->AddReceptionPath(); + receptionPaths++; } } } void -LorawanMacHelper::ApplyCommonSingleChannelConfigurations (Ptr lorawanMac) const +LorawanMacHelper::ApplyCommonSingleChannelConfigurations(Ptr lorawanMac) const { - NS_LOG_FUNCTION_NOARGS (); - - ////////////// - // SubBands // - ////////////// - - LogicalLoraChannelHelper channelHelper; - channelHelper.AddSubBand (868, 868.6, 0.01, 14); - channelHelper.AddSubBand (868.7, 869.2, 0.001, 14); - channelHelper.AddSubBand (869.4, 869.65, 0.1, 27); - - ////////////////////// - // Default channels // - ////////////////////// - Ptr lc1 = CreateObject (868.1, 0, 5); - channelHelper.AddChannel (lc1); - - lorawanMac->SetLogicalLoraChannelHelper (channelHelper); - - /////////////////////////////////////////////// - // DataRate -> SF, DataRate -> Bandwidth // - // and DataRate -> MaxAppPayload conversions // - /////////////////////////////////////////////// - lorawanMac->SetSfForDataRate (std::vector{12, 11, 10, 9, 8, 7, 7}); - lorawanMac->SetBandwidthForDataRate ( - std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); - lorawanMac->SetMaxAppPayloadForDataRate ( - std::vector{59, 59, 59, 123, 230, 230, 230, 230}); + NS_LOG_FUNCTION_NOARGS(); + + ////////////// + // SubBands // + ////////////// + + LogicalLoraChannelHelper channelHelper; + channelHelper.AddSubBand(868, 868.6, 0.01, 14); + channelHelper.AddSubBand(868.7, 869.2, 0.001, 14); + channelHelper.AddSubBand(869.4, 869.65, 0.1, 27); + + ////////////////////// + // Default channels // + ////////////////////// + Ptr lc1 = CreateObject(868.1, 0, 5); + channelHelper.AddChannel(lc1); + + lorawanMac->SetLogicalLoraChannelHelper(channelHelper); + + /////////////////////////////////////////////// + // DataRate -> SF, DataRate -> Bandwidth // + // and DataRate -> MaxAppPayload conversions // + /////////////////////////////////////////////// + lorawanMac->SetSfForDataRate(std::vector{12, 11, 10, 9, 8, 7, 7}); + lorawanMac->SetBandwidthForDataRate( + std::vector{125000, 125000, 125000, 125000, 125000, 125000, 250000}); + lorawanMac->SetMaxAppPayloadForDataRate( + std::vector{59, 59, 59, 123, 230, 230, 230, 230}); } std::vector -LorawanMacHelper::SetSpreadingFactorsUp (NodeContainer endDevices, NodeContainer gateways, - Ptr channel) +LorawanMacHelper::SetSpreadingFactorsUp(NodeContainer endDevices, + NodeContainer gateways, + Ptr channel) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - std::vector sfQuantity (7, 0); - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + std::vector sfQuantity(7, 0); + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr object = *j; - Ptr position = object->GetObject (); - NS_ASSERT (position); - Ptr netDevice = object->GetDevice (0); - Ptr loraNetDevice = netDevice->GetObject (); - NS_ASSERT (loraNetDevice); - Ptr mac = - loraNetDevice->GetMac ()->GetObject (); - NS_ASSERT (mac); - - // Try computing the distance from each gateway and find the best one - Ptr bestGateway = gateways.Get (0); - Ptr bestGatewayPosition = bestGateway->GetObject (); - - // Assume devices transmit at 14 dBm - double highestRxPower = channel->GetRxPower (14, position, bestGatewayPosition); - - for (NodeContainer::Iterator currentGw = gateways.Begin () + 1; currentGw != gateways.End (); - ++currentGw) + Ptr object = *j; + Ptr position = object->GetObject(); + NS_ASSERT(position); + Ptr netDevice = object->GetDevice(0); + Ptr loraNetDevice = netDevice->GetObject(); + NS_ASSERT(loraNetDevice); + Ptr mac = + loraNetDevice->GetMac()->GetObject(); + NS_ASSERT(mac); + + // Try computing the distance from each gateway and find the best one + Ptr bestGateway = gateways.Get(0); + Ptr bestGatewayPosition = bestGateway->GetObject(); + + // Assume devices transmit at 14 dBm + double highestRxPower = channel->GetRxPower(14, position, bestGatewayPosition); + + for (NodeContainer::Iterator currentGw = gateways.Begin() + 1; currentGw != gateways.End(); + ++currentGw) { - // Compute the power received from the current gateway - Ptr curr = *currentGw; - Ptr currPosition = curr->GetObject (); - double currentRxPower = channel->GetRxPower (14, position, currPosition); // dBm + // Compute the power received from the current gateway + Ptr curr = *currentGw; + Ptr currPosition = curr->GetObject(); + double currentRxPower = channel->GetRxPower(14, position, currPosition); // dBm - if (currentRxPower > highestRxPower) + if (currentRxPower > highestRxPower) { - bestGateway = curr; - bestGatewayPosition = curr->GetObject (); - highestRxPower = currentRxPower; + bestGateway = curr; + bestGatewayPosition = curr->GetObject(); + highestRxPower = currentRxPower; } } - // NS_LOG_DEBUG ("Rx Power: " << highestRxPower); - double rxPower = highestRxPower; + // NS_LOG_DEBUG ("Rx Power: " << highestRxPower); + double rxPower = highestRxPower; - // Get the ED sensitivity - Ptr edPhy = loraNetDevice->GetPhy ()->GetObject (); - const double *edSensitivity = edPhy->sensitivity; + // Get the ED sensitivity + Ptr edPhy = loraNetDevice->GetPhy()->GetObject(); + const double* edSensitivity = edPhy->sensitivity; - if (rxPower > *edSensitivity) + if (rxPower > *edSensitivity) { - mac->SetDataRate (5); - sfQuantity[0] = sfQuantity[0] + 1; + mac->SetDataRate(5); + sfQuantity[0] = sfQuantity[0] + 1; } - else if (rxPower > *(edSensitivity + 1)) + else if (rxPower > *(edSensitivity + 1)) { - mac->SetDataRate (4); - sfQuantity[1] = sfQuantity[1] + 1; + mac->SetDataRate(4); + sfQuantity[1] = sfQuantity[1] + 1; } - else if (rxPower > *(edSensitivity + 2)) + else if (rxPower > *(edSensitivity + 2)) { - mac->SetDataRate (3); - sfQuantity[2] = sfQuantity[2] + 1; + mac->SetDataRate(3); + sfQuantity[2] = sfQuantity[2] + 1; } - else if (rxPower > *(edSensitivity + 3)) + else if (rxPower > *(edSensitivity + 3)) { - mac->SetDataRate (2); - sfQuantity[3] = sfQuantity[3] + 1; + mac->SetDataRate(2); + sfQuantity[3] = sfQuantity[3] + 1; } - else if (rxPower > *(edSensitivity + 4)) + else if (rxPower > *(edSensitivity + 4)) { - mac->SetDataRate (1); - sfQuantity[4] = sfQuantity[4] + 1; + mac->SetDataRate(1); + sfQuantity[4] = sfQuantity[4] + 1; } - else if (rxPower > *(edSensitivity + 5)) + else if (rxPower > *(edSensitivity + 5)) { - mac->SetDataRate (0); - sfQuantity[5] = sfQuantity[5] + 1; + mac->SetDataRate(0); + sfQuantity[5] = sfQuantity[5] + 1; } - else // Device is out of range. Assign SF12. + else // Device is out of range. Assign SF12. { - // NS_LOG_DEBUG ("Device out of range"); - mac->SetDataRate (0); - sfQuantity[6] = sfQuantity[6] + 1; - // NS_LOG_DEBUG ("sfQuantity[6] = " << sfQuantity[6]); + // NS_LOG_DEBUG ("Device out of range"); + mac->SetDataRate(0); + sfQuantity[6] = sfQuantity[6] + 1; + // NS_LOG_DEBUG ("sfQuantity[6] = " << sfQuantity[6]); } - /* + /* - // Get the Gw sensitivity - Ptr gatewayNetDevice = bestGateway->GetDevice (0); - Ptr gatewayLoraNetDevice = gatewayNetDevice->GetObject (); - Ptr gatewayPhy = gatewayLoraNetDevice->GetPhy ()->GetObject (); - const double *gwSensitivity = gatewayPhy->sensitivity; + // Get the Gw sensitivity + Ptr gatewayNetDevice = bestGateway->GetDevice (0); + Ptr gatewayLoraNetDevice = gatewayNetDevice->GetObject (); + Ptr gatewayPhy = gatewayLoraNetDevice->GetPhy ()->GetObject + (); const double *gwSensitivity = gatewayPhy->sensitivity; - if(rxPower > *gwSensitivity) - { - mac->SetDataRate (5); - sfQuantity[0] = sfQuantity[0] + 1; + if(rxPower > *gwSensitivity) + { + mac->SetDataRate (5); + sfQuantity[0] = sfQuantity[0] + 1; - } - else if (rxPower > *(gwSensitivity+1)) - { - mac->SetDataRate (4); - sfQuantity[1] = sfQuantity[1] + 1; + } + else if (rxPower > *(gwSensitivity+1)) + { + mac->SetDataRate (4); + sfQuantity[1] = sfQuantity[1] + 1; - } - else if (rxPower > *(gwSensitivity+2)) - { - mac->SetDataRate (3); - sfQuantity[2] = sfQuantity[2] + 1; + } + else if (rxPower > *(gwSensitivity+2)) + { + mac->SetDataRate (3); + sfQuantity[2] = sfQuantity[2] + 1; - } - else if (rxPower > *(gwSensitivity+3)) - { - mac->SetDataRate (2); - sfQuantity[3] = sfQuantity[3] + 1; - } - else if (rxPower > *(gwSensitivity+4)) - { - mac->SetDataRate (1); - sfQuantity[4] = sfQuantity[4] + 1; - } - else if (rxPower > *(gwSensitivity+5)) - { - mac->SetDataRate (0); - sfQuantity[5] = sfQuantity[5] + 1; + } + else if (rxPower > *(gwSensitivity+3)) + { + mac->SetDataRate (2); + sfQuantity[3] = sfQuantity[3] + 1; + } + else if (rxPower > *(gwSensitivity+4)) + { + mac->SetDataRate (1); + sfQuantity[4] = sfQuantity[4] + 1; + } + else if (rxPower > *(gwSensitivity+5)) + { + mac->SetDataRate (0); + sfQuantity[5] = sfQuantity[5] + 1; - } - else // Device is out of range. Assign SF12. - { - mac->SetDataRate (0); - sfQuantity[6] = sfQuantity[6] + 1; + } + else // Device is out of range. Assign SF12. + { + mac->SetDataRate (0); + sfQuantity[6] = sfQuantity[6] + 1; - } - */ + } + */ } // end loop on nodes - return sfQuantity; + return sfQuantity; } // end function std::vector -LorawanMacHelper::SetSpreadingFactorsGivenDistribution (NodeContainer endDevices, - NodeContainer gateways, - std::vector distribution) +LorawanMacHelper::SetSpreadingFactorsGivenDistribution(NodeContainer endDevices, + NodeContainer gateways, + std::vector distribution) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - std::vector sfQuantity (7, 0); - Ptr uniformRV = CreateObject (); - std::vector cumdistr (6); - cumdistr[0] = distribution[0]; - for (int i = 1; i < 7; ++i) + std::vector sfQuantity(7, 0); + Ptr uniformRV = CreateObject(); + std::vector cumdistr(6); + cumdistr[0] = distribution[0]; + for (int i = 1; i < 7; ++i) { - cumdistr[i] = distribution[i] + cumdistr[i - 1]; + cumdistr[i] = distribution[i] + cumdistr[i - 1]; } - NS_LOG_DEBUG ("Distribution: " << distribution[0] << " " << distribution[1] << " " - << distribution[2] << " " << distribution[3] << " " - << distribution[4] << " " << distribution[5]); - NS_LOG_DEBUG ("Cumulative distribution: " << cumdistr[0] << " " << cumdistr[1] << " " - << cumdistr[2] << " " << cumdistr[3] << " " - << cumdistr[4] << " " << cumdistr[5]); + NS_LOG_DEBUG("Distribution: " << distribution[0] << " " << distribution[1] << " " + << distribution[2] << " " << distribution[3] << " " + << distribution[4] << " " << distribution[5]); + NS_LOG_DEBUG("Cumulative distribution: " << cumdistr[0] << " " << cumdistr[1] << " " + << cumdistr[2] << " " << cumdistr[3] << " " + << cumdistr[4] << " " << cumdistr[5]); - for (NodeContainer::Iterator j = endDevices.Begin (); j != endDevices.End (); ++j) + for (NodeContainer::Iterator j = endDevices.Begin(); j != endDevices.End(); ++j) { - Ptr object = *j; - Ptr position = object->GetObject (); - NS_ASSERT (position); - Ptr netDevice = object->GetDevice (0); - Ptr loraNetDevice = netDevice->GetObject (); - NS_ASSERT (loraNetDevice); - Ptr mac = - loraNetDevice->GetMac ()->GetObject (); - NS_ASSERT (mac); - - double prob = uniformRV->GetValue (0, 1); - - // NS_LOG_DEBUG ("Probability: " << prob); - if (prob < cumdistr[0]) + Ptr object = *j; + Ptr position = object->GetObject(); + NS_ASSERT(position); + Ptr netDevice = object->GetDevice(0); + Ptr loraNetDevice = netDevice->GetObject(); + NS_ASSERT(loraNetDevice); + Ptr mac = + loraNetDevice->GetMac()->GetObject(); + NS_ASSERT(mac); + + double prob = uniformRV->GetValue(0, 1); + + // NS_LOG_DEBUG ("Probability: " << prob); + if (prob < cumdistr[0]) { - mac->SetDataRate (5); - sfQuantity[0] = sfQuantity[0] + 1; + mac->SetDataRate(5); + sfQuantity[0] = sfQuantity[0] + 1; } - else if (prob > cumdistr[0] && prob < cumdistr[1]) + else if (prob > cumdistr[0] && prob < cumdistr[1]) { - mac->SetDataRate (4); - sfQuantity[1] = sfQuantity[1] + 1; + mac->SetDataRate(4); + sfQuantity[1] = sfQuantity[1] + 1; } - else if (prob > cumdistr[1] && prob < cumdistr[2]) + else if (prob > cumdistr[1] && prob < cumdistr[2]) { - mac->SetDataRate (3); - sfQuantity[2] = sfQuantity[2] + 1; + mac->SetDataRate(3); + sfQuantity[2] = sfQuantity[2] + 1; } - else if (prob > cumdistr[2] && prob < cumdistr[3]) + else if (prob > cumdistr[2] && prob < cumdistr[3]) { - mac->SetDataRate (2); - sfQuantity[3] = sfQuantity[3] + 1; + mac->SetDataRate(2); + sfQuantity[3] = sfQuantity[3] + 1; } - else if (prob > cumdistr[3] && prob < cumdistr[4]) + else if (prob > cumdistr[3] && prob < cumdistr[4]) { - mac->SetDataRate (1); - sfQuantity[4] = sfQuantity[4] + 1; + mac->SetDataRate(1); + sfQuantity[4] = sfQuantity[4] + 1; } - else + else { - mac->SetDataRate (0); - sfQuantity[5] = sfQuantity[5] + 1; + mac->SetDataRate(0); + sfQuantity[5] = sfQuantity[5] + 1; } } // end loop on nodes - return sfQuantity; + return sfQuantity; } // end function diff --git a/helper/lorawan-mac-helper.h b/helper/lorawan-mac-helper.h index e472fa1e44..92b0652cbf 100644 --- a/helper/lorawan-mac-helper.h +++ b/helper/lorawan-mac-helper.h @@ -21,155 +21,163 @@ #ifndef LORAWAN_MAC_HELPER_H #define LORAWAN_MAC_HELPER_H -#include "ns3/net-device.h" +#include "ns3/class-a-end-device-lorawan-mac.h" +#include "ns3/gateway-lorawan-mac.h" #include "ns3/lora-channel.h" +#include "ns3/lora-device-address-generator.h" #include "ns3/lora-phy.h" #include "ns3/lorawan-mac.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/lora-device-address-generator.h" -#include "ns3/gateway-lorawan-mac.h" +#include "ns3/net-device.h" #include "ns3/node-container.h" #include "ns3/random-variable-stream.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LorawanMacHelper { -public: - /** - * Define the kind of device. Can be either GW (Gateway) or ED (End Device). - */ - enum DeviceType { GW, ED_A }; - - /** - * Define the operational region. - */ - enum Regions { - EU, - US, - China, - EU433MHz, - Australia, - CN, - AS923MHz, - SouthKorea, - SingleChannel, - ALOHA - }; - - /** - * Create a mac helper without any parameter set. The user must set - * them all to be able to call Install later. - */ - LorawanMacHelper (); - - /** - * Set an attribute of the underlying MAC object. - * - * \param name the name of the attribute to set. - * \param v the value of the attribute. - */ - void Set (std::string name, const AttributeValue &v); - - /** - * Set the address generator to use for creation of these nodes. - */ - void SetAddressGenerator (Ptr addrGen); - - /** - * Set the kind of MAC this helper will create. - * - * \param dt the device type (either gateway or end device). - */ - void SetDeviceType (enum DeviceType dt); - - /** - * Set the region in which the device is to operate. - */ - void SetRegion (enum Regions region); - - /** - * Create the LorawanMac instance and connect it to a device - * - * \param node the node on which we wish to create a wifi MAC. - * \param device the device within which this MAC will be created. - * \returns a newly-created LorawanMac object. - */ - Ptr Create (Ptr node, Ptr device) const; - - /** - * Set up the end device's data rates - * This function assumes we are using the following convention: - * SF7 -> DR5 - * SF8 -> DR4 - * SF9 -> DR3 - * SF10 -> DR2 - * SF11 -> DR1 - * SF12 -> DR0 - */ - static std::vector SetSpreadingFactorsUp (NodeContainer endDevices, NodeContainer gateways, - Ptr channel); - /** - * Set up the end device's data rates according to the given distribution. - */ - static std::vector SetSpreadingFactorsGivenDistribution (NodeContainer endDevices, - NodeContainer gateways, - std::vector distribution); - -private: - /** - * Perform region-specific configurations for the 868 MHz EU band. - */ - void ConfigureForEuRegion (Ptr edMac) const; - - /** - * Perform region-specific configurations for the 868 MHz EU band. - */ - void ConfigureForEuRegion (Ptr gwMac) const; - - /** - * Apply configurations that are common both for the GatewayLorawanMac and the - * ClassAEndDeviceLorawanMac classes. - */ - void ApplyCommonEuConfigurations (Ptr lorawanMac) const; - - /** - * Perform region-specific configurations for the SINGLECHANNEL band. - */ - void ConfigureForSingleChannelRegion (Ptr edMac) const; - - /** - * Perform region-specific configurations for the SINGLECHANNEL band. - */ - void ConfigureForSingleChannelRegion (Ptr gwMac) const; - - /** - * Apply configurations that are common both for the GatewayLorawanMac and the - * ClassAEndDeviceLorawanMac classes. - */ - void ApplyCommonSingleChannelConfigurations (Ptr lorawanMac) const; - - /** - * Perform region-specific configurations for the ALOHA band. - */ - void ConfigureForAlohaRegion (Ptr edMac) const; - - /** - * Perform region-specific configurations for the ALOHA band. - */ - void ConfigureForAlohaRegion (Ptr gwMac) const; - - /** - * Apply configurations that are common both for the GatewayLorawanMac and the - * ClassAEndDeviceLorawanMac classes. - */ - void ApplyCommonAlohaConfigurations (Ptr lorawanMac) const; - - ObjectFactory m_mac; - Ptr m_addrGen; //!< Pointer to the address generator to use - enum DeviceType m_deviceType; //!< The kind of device to install - enum Regions m_region; //!< The region in which the device will operate + public: + /** + * Define the kind of device. Can be either GW (Gateway) or ED (End Device). + */ + enum DeviceType + { + GW, + ED_A + }; + + /** + * Define the operational region. + */ + enum Regions + { + EU, + US, + China, + EU433MHz, + Australia, + CN, + AS923MHz, + SouthKorea, + SingleChannel, + ALOHA + }; + + /** + * Create a mac helper without any parameter set. The user must set + * them all to be able to call Install later. + */ + LorawanMacHelper(); + + /** + * Set an attribute of the underlying MAC object. + * + * \param name the name of the attribute to set. + * \param v the value of the attribute. + */ + void Set(std::string name, const AttributeValue& v); + + /** + * Set the address generator to use for creation of these nodes. + */ + void SetAddressGenerator(Ptr addrGen); + + /** + * Set the kind of MAC this helper will create. + * + * \param dt the device type (either gateway or end device). + */ + void SetDeviceType(enum DeviceType dt); + + /** + * Set the region in which the device is to operate. + */ + void SetRegion(enum Regions region); + + /** + * Create the LorawanMac instance and connect it to a device + * + * \param node the node on which we wish to create a wifi MAC. + * \param device the device within which this MAC will be created. + * \returns a newly-created LorawanMac object. + */ + Ptr Create(Ptr node, Ptr device) const; + + /** + * Set up the end device's data rates + * This function assumes we are using the following convention: + * SF7 -> DR5 + * SF8 -> DR4 + * SF9 -> DR3 + * SF10 -> DR2 + * SF11 -> DR1 + * SF12 -> DR0 + */ + static std::vector SetSpreadingFactorsUp(NodeContainer endDevices, + NodeContainer gateways, + Ptr channel); + /** + * Set up the end device's data rates according to the given distribution. + */ + static std::vector SetSpreadingFactorsGivenDistribution(NodeContainer endDevices, + NodeContainer gateways, + std::vector distribution); + + private: + /** + * Perform region-specific configurations for the 868 MHz EU band. + */ + void ConfigureForEuRegion(Ptr edMac) const; + + /** + * Perform region-specific configurations for the 868 MHz EU band. + */ + void ConfigureForEuRegion(Ptr gwMac) const; + + /** + * Apply configurations that are common both for the GatewayLorawanMac and the + * ClassAEndDeviceLorawanMac classes. + */ + void ApplyCommonEuConfigurations(Ptr lorawanMac) const; + + /** + * Perform region-specific configurations for the SINGLECHANNEL band. + */ + void ConfigureForSingleChannelRegion(Ptr edMac) const; + + /** + * Perform region-specific configurations for the SINGLECHANNEL band. + */ + void ConfigureForSingleChannelRegion(Ptr gwMac) const; + + /** + * Apply configurations that are common both for the GatewayLorawanMac and the + * ClassAEndDeviceLorawanMac classes. + */ + void ApplyCommonSingleChannelConfigurations(Ptr lorawanMac) const; + + /** + * Perform region-specific configurations for the ALOHA band. + */ + void ConfigureForAlohaRegion(Ptr edMac) const; + + /** + * Perform region-specific configurations for the ALOHA band. + */ + void ConfigureForAlohaRegion(Ptr gwMac) const; + + /** + * Apply configurations that are common both for the GatewayLorawanMac and the + * ClassAEndDeviceLorawanMac classes. + */ + void ApplyCommonAlohaConfigurations(Ptr lorawanMac) const; + + ObjectFactory m_mac; + Ptr m_addrGen; //!< Pointer to the address generator to use + enum DeviceType m_deviceType; //!< The kind of device to install + enum Regions m_region; //!< The region in which the device will operate }; } // namespace lorawan diff --git a/helper/network-server-helper.cc b/helper/network-server-helper.cc index dc4f8f8296..1205fd6807 100644 --- a/helper/network-server-helper.cc +++ b/helper/network-server-helper.cc @@ -18,145 +18,143 @@ * Author: Davide Magrin */ -#include "ns3/network-server-helper.h" -#include "ns3/network-controller-components.h" +#include "network-server-helper.h" + #include "ns3/adr-component.h" #include "ns3/double.h" +#include "ns3/log.h" +#include "ns3/network-controller-components.h" +#include "ns3/simulator.h" #include "ns3/string.h" #include "ns3/trace-source-accessor.h" -#include "ns3/simulator.h" -#include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkServerHelper"); +NS_LOG_COMPONENT_DEFINE("NetworkServerHelper"); -NetworkServerHelper::NetworkServerHelper () +NetworkServerHelper::NetworkServerHelper() { - m_factory.SetTypeId ("ns3::NetworkServer"); - p2pHelper.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); - p2pHelper.SetChannelAttribute ("Delay", StringValue ("2ms")); - SetAdr ("ns3::AdrComponent"); + m_factory.SetTypeId("ns3::NetworkServer"); + p2pHelper.SetDeviceAttribute("DataRate", StringValue("5Mbps")); + p2pHelper.SetChannelAttribute("Delay", StringValue("2ms")); + SetAdr("ns3::AdrComponent"); } -NetworkServerHelper::~NetworkServerHelper () +NetworkServerHelper::~NetworkServerHelper() { } void -NetworkServerHelper::SetAttribute (std::string name, const AttributeValue &value) +NetworkServerHelper::SetAttribute(std::string name, const AttributeValue& value) { - m_factory.Set (name, value); + m_factory.Set(name, value); } void -NetworkServerHelper::SetGateways (NodeContainer gateways) +NetworkServerHelper::SetGateways(NodeContainer gateways) { - m_gateways = gateways; + m_gateways = gateways; } void -NetworkServerHelper::SetEndDevices (NodeContainer endDevices) +NetworkServerHelper::SetEndDevices(NodeContainer endDevices) { - m_endDevices = endDevices; + m_endDevices = endDevices; } ApplicationContainer -NetworkServerHelper::Install (Ptr node) +NetworkServerHelper::Install(Ptr node) { - return ApplicationContainer (InstallPriv (node)); + return ApplicationContainer(InstallPriv(node)); } ApplicationContainer -NetworkServerHelper::Install (NodeContainer c) +NetworkServerHelper::Install(NodeContainer c) { - ApplicationContainer apps; - for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + ApplicationContainer apps; + for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) { - apps.Add (InstallPriv (*i)); + apps.Add(InstallPriv(*i)); } - return apps; + return apps; } Ptr -NetworkServerHelper::InstallPriv (Ptr node) +NetworkServerHelper::InstallPriv(Ptr node) { - NS_LOG_FUNCTION (this << node); + NS_LOG_FUNCTION(this << node); - Ptr app = m_factory.Create (); + Ptr app = m_factory.Create(); - app->SetNode (node); - node->AddApplication (app); + app->SetNode(node); + node->AddApplication(app); - // Cycle on each gateway - for (NodeContainer::Iterator i = m_gateways.Begin (); - i != m_gateways.End (); - i++) + // Cycle on each gateway + for (NodeContainer::Iterator i = m_gateways.Begin(); i != m_gateways.End(); i++) { - // Add the connections with the gateway - // Create a PointToPoint link between gateway and NS - NetDeviceContainer container = p2pHelper.Install (node, *i); + // Add the connections with the gateway + // Create a PointToPoint link between gateway and NS + NetDeviceContainer container = p2pHelper.Install(node, *i); - // Add the gateway to the NS list - app->AddGateway (*i, container.Get (0)); + // Add the gateway to the NS list + app->AddGateway(*i, container.Get(0)); } - // Link the NetworkServer to its NetDevices - for (uint32_t i = 0; i < node->GetNDevices (); i++) + // Link the NetworkServer to its NetDevices + for (uint32_t i = 0; i < node->GetNDevices(); i++) { - Ptr currentNetDevice = node->GetDevice (i); - currentNetDevice->SetReceiveCallback (MakeCallback - (&NetworkServer::Receive, - app)); + Ptr currentNetDevice = node->GetDevice(i); + currentNetDevice->SetReceiveCallback(MakeCallback(&NetworkServer::Receive, app)); } - // Add the end devices - app->AddNodes (m_endDevices); + // Add the end devices + app->AddNodes(m_endDevices); - // Add components to the NetworkServer - InstallComponents (app); + // Add components to the NetworkServer + InstallComponents(app); - return app; + return app; } void -NetworkServerHelper::EnableAdr (bool enableAdr) +NetworkServerHelper::EnableAdr(bool enableAdr) { - NS_LOG_FUNCTION (this << enableAdr); + NS_LOG_FUNCTION(this << enableAdr); - m_adrEnabled = enableAdr; + m_adrEnabled = enableAdr; } void -NetworkServerHelper::SetAdr (std::string type) +NetworkServerHelper::SetAdr(std::string type) { - NS_LOG_FUNCTION (this << type); + NS_LOG_FUNCTION(this << type); - m_adrSupportFactory = ObjectFactory (); - m_adrSupportFactory.SetTypeId (type); + m_adrSupportFactory = ObjectFactory(); + m_adrSupportFactory.SetTypeId(type); } void -NetworkServerHelper::InstallComponents (Ptr netServer) +NetworkServerHelper::InstallComponents(Ptr netServer) { - NS_LOG_FUNCTION (this << netServer); + NS_LOG_FUNCTION(this << netServer); - // Add Confirmed Messages support - Ptr ackSupport = - CreateObject (); - netServer->AddComponent (ackSupport); + // Add Confirmed Messages support + Ptr ackSupport = CreateObject(); + netServer->AddComponent(ackSupport); - // Add LinkCheck support - Ptr linkCheckSupport = CreateObject (); - netServer->AddComponent (linkCheckSupport); + // Add LinkCheck support + Ptr linkCheckSupport = CreateObject(); + netServer->AddComponent(linkCheckSupport); - // Add Adr support - if (m_adrEnabled) + // Add Adr support + if (m_adrEnabled) { - netServer->AddComponent (m_adrSupportFactory.Create ()); + netServer->AddComponent(m_adrSupportFactory.Create()); } } -} +} // namespace lorawan } // namespace ns3 diff --git a/helper/network-server-helper.h b/helper/network-server-helper.h index 4d3b454754..104c0f7c11 100644 --- a/helper/network-server-helper.h +++ b/helper/network-server-helper.h @@ -21,76 +21,79 @@ #ifndef NETWORK_SERVER_HELPER_H #define NETWORK_SERVER_HELPER_H -#include "ns3/object-factory.h" #include "ns3/address.h" +#include "ns3/application-container.h" #include "ns3/attribute.h" #include "ns3/net-device.h" +#include "ns3/network-server.h" #include "ns3/node-container.h" -#include "ns3/application-container.h" +#include "ns3/object-factory.h" #include "ns3/point-to-point-helper.h" -#include "ns3/network-server.h" + #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class can install Network Server applications on multiple nodes at once. */ class NetworkServerHelper { -public: - NetworkServerHelper (); + public: + NetworkServerHelper(); - ~NetworkServerHelper (); + ~NetworkServerHelper(); - void SetAttribute (std::string name, const AttributeValue &value); + void SetAttribute(std::string name, const AttributeValue& value); - ApplicationContainer Install (NodeContainer c); + ApplicationContainer Install(NodeContainer c); - ApplicationContainer Install (Ptr node); + ApplicationContainer Install(Ptr node); - /** - * Set which gateways will need to be connected to this NS. - */ - void SetGateways (NodeContainer gateways); + /** + * Set which gateways will need to be connected to this NS. + */ + void SetGateways(NodeContainer gateways); - /** - * Set which end devices will be managed by this NS. - */ - void SetEndDevices (NodeContainer endDevices); + /** + * Set which end devices will be managed by this NS. + */ + void SetEndDevices(NodeContainer endDevices); - /** - * Enable (true) or disable (false) the ADR component in the Network - * Server created by this helper. - */ - void EnableAdr (bool enableAdr); + /** + * Enable (true) or disable (false) the ADR component in the Network + * Server created by this helper. + */ + void EnableAdr(bool enableAdr); - /** - * Set the ADR implementation to use in the Network Server created - * by this helper. - */ - void SetAdr (std::string type); + /** + * Set the ADR implementation to use in the Network Server created + * by this helper. + */ + void SetAdr(std::string type); -private: - void InstallComponents (Ptr netServer); - Ptr InstallPriv (Ptr node); + private: + void InstallComponents(Ptr netServer); + Ptr InstallPriv(Ptr node); - ObjectFactory m_factory; + ObjectFactory m_factory; - NodeContainer m_gateways; //!< Set of gateways to connect to this NS + NodeContainer m_gateways; //!< Set of gateways to connect to this NS - NodeContainer m_endDevices; //!< Set of endDevices to connect to this NS + NodeContainer m_endDevices; //!< Set of endDevices to connect to this NS - PointToPointHelper p2pHelper; //!< Helper to create PointToPoint links + PointToPointHelper p2pHelper; //!< Helper to create PointToPoint links - bool m_adrEnabled; + bool m_adrEnabled; - ObjectFactory m_adrSupportFactory; + ObjectFactory m_adrSupportFactory; }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* NETWORK_SERVER_HELPER_H */ diff --git a/helper/one-shot-sender-helper.cc b/helper/one-shot-sender-helper.cc index 36b8b325e6..d59780465d 100644 --- a/helper/one-shot-sender-helper.cc +++ b/helper/one-shot-sender-helper.cc @@ -18,72 +18,74 @@ * Author: Davide Magrin */ -#include "ns3/one-shot-sender-helper.h" -#include "ns3/one-shot-sender.h" +#include "one-shot-sender-helper.h" + #include "ns3/double.h" +#include "ns3/log.h" +#include "ns3/one-shot-sender.h" +#include "ns3/simulator.h" #include "ns3/string.h" #include "ns3/trace-source-accessor.h" -#include "ns3/simulator.h" -#include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("OneShotSenderHelper"); +NS_LOG_COMPONENT_DEFINE("OneShotSenderHelper"); -OneShotSenderHelper::OneShotSenderHelper () +OneShotSenderHelper::OneShotSenderHelper() { - m_factory.SetTypeId ("ns3::OneShotSender"); + m_factory.SetTypeId("ns3::OneShotSender"); } -OneShotSenderHelper::~OneShotSenderHelper () +OneShotSenderHelper::~OneShotSenderHelper() { } void -OneShotSenderHelper::SetSendTime (Time sendTime) +OneShotSenderHelper::SetSendTime(Time sendTime) { - m_sendTime = sendTime; + m_sendTime = sendTime; } void -OneShotSenderHelper::SetAttribute (std::string name, - const AttributeValue &value) +OneShotSenderHelper::SetAttribute(std::string name, const AttributeValue& value) { - m_factory.Set (name, value); + m_factory.Set(name, value); } ApplicationContainer -OneShotSenderHelper::Install (Ptr node) const +OneShotSenderHelper::Install(Ptr node) const { - return ApplicationContainer (InstallPriv (node)); + return ApplicationContainer(InstallPriv(node)); } ApplicationContainer -OneShotSenderHelper::Install (NodeContainer c) const +OneShotSenderHelper::Install(NodeContainer c) const { - ApplicationContainer apps; - for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + ApplicationContainer apps; + for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) { - apps.Add (InstallPriv (*i)); + apps.Add(InstallPriv(*i)); } - return apps; + return apps; } Ptr -OneShotSenderHelper::InstallPriv (Ptr node) const +OneShotSenderHelper::InstallPriv(Ptr node) const { - NS_LOG_FUNCTION (this << node->GetId ()); + NS_LOG_FUNCTION(this << node->GetId()); - Ptr app = m_factory.Create (); + Ptr app = m_factory.Create(); - app->SetSendTime (m_sendTime); + app->SetSendTime(m_sendTime); - app->SetNode (node); - node->AddApplication (app); + app->SetNode(node); + node->AddApplication(app); - return app; -} + return app; } +} // namespace lorawan } // namespace ns3 diff --git a/helper/one-shot-sender-helper.h b/helper/one-shot-sender-helper.h index d67fe996f3..ce46e18ca7 100644 --- a/helper/one-shot-sender-helper.h +++ b/helper/one-shot-sender-helper.h @@ -21,18 +21,21 @@ #ifndef ONE_SHOT_SENDER_HELPER_H #define ONE_SHOT_SENDER_HELPER_H -#include "ns3/object-factory.h" #include "ns3/address.h" +#include "ns3/application-container.h" #include "ns3/attribute.h" #include "ns3/net-device.h" #include "ns3/node-container.h" -#include "ns3/application-container.h" +#include "ns3/object-factory.h" #include "ns3/one-shot-sender.h" + #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class can be used to install OneShotSender applications on multiple @@ -40,29 +43,29 @@ namespace lorawan { */ class OneShotSenderHelper { -public: - OneShotSenderHelper (); + public: + OneShotSenderHelper(); - ~OneShotSenderHelper (); + ~OneShotSenderHelper(); - void SetAttribute (std::string name, const AttributeValue &value); + void SetAttribute(std::string name, const AttributeValue& value); - ApplicationContainer Install (NodeContainer c) const; + ApplicationContainer Install(NodeContainer c) const; - ApplicationContainer Install (Ptr node) const; + ApplicationContainer Install(Ptr node) const; - void SetSendTime (Time sendTime); + void SetSendTime(Time sendTime); -private: - Ptr InstallPriv (Ptr node) const; + private: + Ptr InstallPriv(Ptr node) const; - ObjectFactory m_factory; + ObjectFactory m_factory; - Time m_sendTime; //!< Time at which the OneShotSender will be configured to - //send the packet + Time m_sendTime; //!< Time at which the OneShotSender will be configured to + // send the packet }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* ONE_SHOT_SENDER_HELPER_H */ diff --git a/helper/periodic-sender-helper.cc b/helper/periodic-sender-helper.cc index 205048bfcb..0abd57d823 100644 --- a/helper/periodic-sender-helper.cc +++ b/helper/periodic-sender-helper.cc @@ -18,136 +18,138 @@ * Author: Davide Magrin */ -#include "ns3/periodic-sender-helper.h" -#include "ns3/random-variable-stream.h" -#include "ns3/periodic-sender.h" +#include "periodic-sender-helper.h" + #include "ns3/double.h" +#include "ns3/log.h" +#include "ns3/periodic-sender.h" +#include "ns3/random-variable-stream.h" +#include "ns3/simulator.h" #include "ns3/string.h" #include "ns3/trace-source-accessor.h" -#include "ns3/simulator.h" -#include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("PeriodicSenderHelper"); +NS_LOG_COMPONENT_DEFINE("PeriodicSenderHelper"); -PeriodicSenderHelper::PeriodicSenderHelper () +PeriodicSenderHelper::PeriodicSenderHelper() { - m_factory.SetTypeId ("ns3::PeriodicSender"); + m_factory.SetTypeId("ns3::PeriodicSender"); - // m_factory.Set ("PacketSizeRandomVariable", StringValue - // ("ns3::ParetoRandomVariable[Bound=10|Shape=2.5]")); + // m_factory.Set ("PacketSizeRandomVariable", StringValue + // ("ns3::ParetoRandomVariable[Bound=10|Shape=2.5]")); - m_initialDelay = CreateObject (); - m_initialDelay->SetAttribute ("Min", DoubleValue (0)); + m_initialDelay = CreateObject(); + m_initialDelay->SetAttribute("Min", DoubleValue(0)); - m_intervalProb = CreateObject (); - m_intervalProb->SetAttribute ("Min", DoubleValue (0)); - m_intervalProb->SetAttribute ("Max", DoubleValue (1)); + m_intervalProb = CreateObject(); + m_intervalProb->SetAttribute("Min", DoubleValue(0)); + m_intervalProb->SetAttribute("Max", DoubleValue(1)); - m_pktSize = 10; - m_pktSizeRV = 0; + m_pktSize = 10; + m_pktSizeRV = 0; } -PeriodicSenderHelper::~PeriodicSenderHelper () +PeriodicSenderHelper::~PeriodicSenderHelper() { } void -PeriodicSenderHelper::SetAttribute (std::string name, const AttributeValue &value) +PeriodicSenderHelper::SetAttribute(std::string name, const AttributeValue& value) { - m_factory.Set (name, value); + m_factory.Set(name, value); } ApplicationContainer -PeriodicSenderHelper::Install (Ptr node) const +PeriodicSenderHelper::Install(Ptr node) const { - return ApplicationContainer (InstallPriv (node)); + return ApplicationContainer(InstallPriv(node)); } ApplicationContainer -PeriodicSenderHelper::Install (NodeContainer c) const +PeriodicSenderHelper::Install(NodeContainer c) const { - ApplicationContainer apps; - for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + ApplicationContainer apps; + for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i) { - apps.Add (InstallPriv (*i)); + apps.Add(InstallPriv(*i)); } - return apps; + return apps; } Ptr -PeriodicSenderHelper::InstallPriv (Ptr node) const +PeriodicSenderHelper::InstallPriv(Ptr node) const { - NS_LOG_FUNCTION (this << node); + NS_LOG_FUNCTION(this << node); - Ptr app = m_factory.Create (); + Ptr app = m_factory.Create(); - Time interval; - if (m_period == Seconds (0)) + Time interval; + if (m_period == Seconds(0)) { - double intervalProb = m_intervalProb->GetValue (); - NS_LOG_DEBUG ("IntervalProb = " << intervalProb); + double intervalProb = m_intervalProb->GetValue(); + NS_LOG_DEBUG("IntervalProb = " << intervalProb); - // Based on TR 45.820 - if (intervalProb < 0.4) + // Based on TR 45.820 + if (intervalProb < 0.4) { - interval = Days (1); + interval = Days(1); } - else if (0.4 <= intervalProb && intervalProb < 0.8) + else if (0.4 <= intervalProb && intervalProb < 0.8) { - interval = Hours (2); + interval = Hours(2); } - else if (0.8 <= intervalProb && intervalProb < 0.95) + else if (0.8 <= intervalProb && intervalProb < 0.95) { - interval = Hours (1); + interval = Hours(1); } - else + else { - interval = Minutes (30); + interval = Minutes(30); } } - else + else { - interval = m_period; + interval = m_period; } - app->SetInterval (interval); - NS_LOG_DEBUG ("Created an application with interval = " << - interval.GetHours () << " hours"); + app->SetInterval(interval); + NS_LOG_DEBUG("Created an application with interval = " << interval.GetHours() << " hours"); - app->SetInitialDelay (Seconds (m_initialDelay->GetValue (0, interval.GetSeconds ()))); - app->SetPacketSize (m_pktSize); - if (m_pktSizeRV) + app->SetInitialDelay(Seconds(m_initialDelay->GetValue(0, interval.GetSeconds()))); + app->SetPacketSize(m_pktSize); + if (m_pktSizeRV) { - app->SetPacketSizeRandomVariable (m_pktSizeRV); + app->SetPacketSizeRandomVariable(m_pktSizeRV); } - app->SetNode (node); - node->AddApplication (app); + app->SetNode(node); + node->AddApplication(app); - return app; + return app; } void -PeriodicSenderHelper::SetPeriod (Time period) +PeriodicSenderHelper::SetPeriod(Time period) { - m_period = period; + m_period = period; } void -PeriodicSenderHelper::SetPacketSizeRandomVariable (Ptr rv) +PeriodicSenderHelper::SetPacketSizeRandomVariable(Ptr rv) { - m_pktSizeRV = rv; + m_pktSizeRV = rv; } void -PeriodicSenderHelper::SetPacketSize (uint8_t size) +PeriodicSenderHelper::SetPacketSize(uint8_t size) { - m_pktSize = size; + m_pktSize = size; } -} +} // namespace lorawan } // namespace ns3 diff --git a/helper/periodic-sender-helper.h b/helper/periodic-sender-helper.h index 1c01aecd9e..6507fc8eef 100644 --- a/helper/periodic-sender-helper.h +++ b/helper/periodic-sender-helper.h @@ -21,18 +21,21 @@ #ifndef PERIODIC_SENDER_HELPER_H #define PERIODIC_SENDER_HELPER_H -#include "ns3/object-factory.h" #include "ns3/address.h" +#include "ns3/application-container.h" #include "ns3/attribute.h" #include "ns3/net-device.h" #include "ns3/node-container.h" -#include "ns3/application-container.h" +#include "ns3/object-factory.h" #include "ns3/periodic-sender.h" + #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class can be used to install PeriodicSender applications on a wide @@ -40,51 +43,50 @@ namespace lorawan { */ class PeriodicSenderHelper { -public: - PeriodicSenderHelper (); - - ~PeriodicSenderHelper (); - - void SetAttribute (std::string name, const AttributeValue &value); + public: + PeriodicSenderHelper(); - ApplicationContainer Install (NodeContainer c) const; + ~PeriodicSenderHelper(); - ApplicationContainer Install (Ptr node) const; + void SetAttribute(std::string name, const AttributeValue& value); - /** - * Set the period to be used by the applications created by this helper. - * - * A value of Seconds (0) results in randomly generated periods according to - * the model contained in the TR 45.820 document. - * - * \param period The period to set - */ - void SetPeriod (Time period); + ApplicationContainer Install(NodeContainer c) const; - void SetPacketSizeRandomVariable (Ptr rv); + ApplicationContainer Install(Ptr node) const; - void SetPacketSize (uint8_t size); + /** + * Set the period to be used by the applications created by this helper. + * + * A value of Seconds (0) results in randomly generated periods according to + * the model contained in the TR 45.820 document. + * + * \param period The period to set + */ + void SetPeriod(Time period); + void SetPacketSizeRandomVariable(Ptr rv); -private: - Ptr InstallPriv (Ptr node) const; + void SetPacketSize(uint8_t size); - ObjectFactory m_factory; + private: + Ptr InstallPriv(Ptr node) const; - Ptr m_initialDelay; + ObjectFactory m_factory; - Ptr m_intervalProb; + Ptr m_initialDelay; - Time m_period; //!< The period with which the application will be set to send - // messages + Ptr m_intervalProb; - Ptr m_pktSizeRV; // whether or not a random component is added to the packet size + Time m_period; //!< The period with which the application will be set to send + // messages - uint8_t m_pktSize; // the packet size. + Ptr + m_pktSizeRV; // whether or not a random component is added to the packet size + uint8_t m_pktSize; // the packet size. }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* PERIODIC_SENDER_HELPER_H */ diff --git a/model/adr-component.cc b/model/adr-component.cc index d299732d05..ca49084eac 100644 --- a/model/adr-component.cc +++ b/model/adr-component.cc @@ -18,457 +18,464 @@ * Author: Matteo Perin () - .SetParent () - .AddAttribute ("MultipleGwCombiningMethod", - "Whether to average the received power of gateways or to use the maximum", - EnumValue (AdrComponent::AVERAGE), - MakeEnumAccessor (&AdrComponent::tpAveraging), - MakeEnumChecker (AdrComponent::AVERAGE, - "avg", - AdrComponent::MAXIMUM, - "max", - AdrComponent::MINIMUM, - "min")) - .AddAttribute ("MultiplePacketsCombiningMethod", - "Whether to average SNRs from multiple packets or to use the maximum", - EnumValue (AdrComponent::AVERAGE), - MakeEnumAccessor (&AdrComponent::historyAveraging), - MakeEnumChecker (AdrComponent::AVERAGE, - "avg", - AdrComponent::MAXIMUM, - "max", - AdrComponent::MINIMUM, - "min")) - .AddAttribute ("HistoryRange", - "Number of packets to use for averaging", - IntegerValue (4), - MakeIntegerAccessor (&AdrComponent::historyRange), - MakeIntegerChecker (0, 100)) - .AddAttribute ("ChangeTransmissionPower", - "Whether to toggle the transmission power or not", - BooleanValue (true), - MakeBooleanAccessor (&AdrComponent::m_toggleTxPower), - MakeBooleanChecker ()) - ; - return tid; + static TypeId tid = + TypeId("ns3::AdrComponent") + .SetGroupName("lorawan") + .AddConstructor() + .SetParent() + .AddAttribute("MultipleGwCombiningMethod", + "Whether to average the received power of gateways or to use the maximum", + EnumValue(AdrComponent::AVERAGE), + MakeEnumAccessor(&AdrComponent::tpAveraging), + MakeEnumChecker(AdrComponent::AVERAGE, + "avg", + AdrComponent::MAXIMUM, + "max", + AdrComponent::MINIMUM, + "min")) + .AddAttribute("MultiplePacketsCombiningMethod", + "Whether to average SNRs from multiple packets or to use the maximum", + EnumValue(AdrComponent::AVERAGE), + MakeEnumAccessor(&AdrComponent::historyAveraging), + MakeEnumChecker(AdrComponent::AVERAGE, + "avg", + AdrComponent::MAXIMUM, + "max", + AdrComponent::MINIMUM, + "min")) + .AddAttribute("HistoryRange", + "Number of packets to use for averaging", + IntegerValue(4), + MakeIntegerAccessor(&AdrComponent::historyRange), + MakeIntegerChecker(0, 100)) + .AddAttribute("ChangeTransmissionPower", + "Whether to toggle the transmission power or not", + BooleanValue(true), + MakeBooleanAccessor(&AdrComponent::m_toggleTxPower), + MakeBooleanChecker()); + return tid; } -AdrComponent::AdrComponent () +AdrComponent::AdrComponent() { } -AdrComponent::~AdrComponent () +AdrComponent::~AdrComponent() { } -void AdrComponent::OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus) +void +AdrComponent::OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this->GetTypeId () << packet << networkStatus); + NS_LOG_FUNCTION(this->GetTypeId() << packet << networkStatus); - // We will only act just before reply, when all Gateways will have received - // the packet, since we need their respective received power. + // We will only act just before reply, when all Gateways will have received + // the packet, since we need their respective received power. } void -AdrComponent::BeforeSendingReply (Ptr status, - Ptr networkStatus) +AdrComponent::BeforeSendingReply(Ptr status, Ptr networkStatus) { - NS_LOG_FUNCTION (this << status << networkStatus); + NS_LOG_FUNCTION(this << status << networkStatus); - Ptr myPacket = status->GetLastPacketReceivedFromDevice ()->Copy (); - LorawanMacHeader mHdr; - LoraFrameHeader fHdr; - fHdr.SetAsUplink (); - myPacket->RemoveHeader (mHdr); - myPacket->RemoveHeader (fHdr); + Ptr myPacket = status->GetLastPacketReceivedFromDevice()->Copy(); + LorawanMacHeader mHdr; + LoraFrameHeader fHdr; + fHdr.SetAsUplink(); + myPacket->RemoveHeader(mHdr); + myPacket->RemoveHeader(fHdr); - //Execute the ADR algotithm only if the request bit is set - if (fHdr.GetAdr ()) + // Execute the ADR algotithm only if the request bit is set + if (fHdr.GetAdr()) { - if (int(status->GetReceivedPacketList ().size ()) < historyRange) + if (int(status->GetReceivedPacketList().size()) < historyRange) { - NS_LOG_ERROR ("Not enough packets received by this device (" << status->GetReceivedPacketList ().size () << ") for the algorithm to work (need " << historyRange << ")"); + NS_LOG_ERROR("Not enough packets received by this device (" + << status->GetReceivedPacketList().size() + << ") for the algorithm to work (need " << historyRange << ")"); } - else + else { - NS_LOG_DEBUG ("New ADR request"); + NS_LOG_DEBUG("New ADR request"); - //Get the SF used by the device - uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor (); + // Get the SF used by the device + uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor(); - //Get the device transmission power (dBm) - uint8_t transmissionPower = status->GetMac ()->GetTransmissionPower (); + // Get the device transmission power (dBm) + uint8_t transmissionPower = status->GetMac()->GetTransmissionPower(); - //New parameters for the end-device - uint8_t newDataRate; - uint8_t newTxPower; + // New parameters for the end-device + uint8_t newDataRate; + uint8_t newTxPower; - //ADR Algorithm - AdrImplementation (&newDataRate, - &newTxPower, - status); + // ADR Algorithm + AdrImplementation(&newDataRate, &newTxPower, status); - // Change the power back to the default if we don't want to change it - if (!m_toggleTxPower) + // Change the power back to the default if we don't want to change it + if (!m_toggleTxPower) { - newTxPower = transmissionPower; + newTxPower = transmissionPower; } - if (newDataRate != SfToDr (spreadingFactor) || newTxPower != transmissionPower) + if (newDataRate != SfToDr(spreadingFactor) || newTxPower != transmissionPower) { - //Create a list with mandatory channel indexes - int channels[] = {0, 1, 2}; - std::list enabledChannels (channels, - channels + sizeof(channels) / - sizeof(int)); + // Create a list with mandatory channel indexes + int channels[] = {0, 1, 2}; + std::list enabledChannels(channels, channels + sizeof(channels) / sizeof(int)); - //Repetitions Setting - const int rep = 1; + // Repetitions Setting + const int rep = 1; - NS_LOG_DEBUG ("Sending LinkAdrReq with DR = " << (unsigned)newDataRate << " and TP = " << (unsigned)newTxPower << " dBm"); + NS_LOG_DEBUG("Sending LinkAdrReq with DR = " << (unsigned)newDataRate + << " and TP = " << (unsigned)newTxPower + << " dBm"); - status->m_reply.frameHeader.AddLinkAdrReq (newDataRate, - GetTxPowerIndex (newTxPower), - enabledChannels, - rep); - status->m_reply.frameHeader.SetAsDownlink (); - status->m_reply.macHeader.SetMType (LorawanMacHeader::UNCONFIRMED_DATA_DOWN); + status->m_reply.frameHeader.AddLinkAdrReq(newDataRate, + GetTxPowerIndex(newTxPower), + enabledChannels, + rep); + status->m_reply.frameHeader.SetAsDownlink(); + status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN); - status->m_reply.needsReply = true; + status->m_reply.needsReply = true; } - else + else { - NS_LOG_DEBUG ("Skipped request"); + NS_LOG_DEBUG("Skipped request"); } } } - else + else { - // Do nothing + // Do nothing } } -void AdrComponent::OnFailedReply (Ptr status, - Ptr networkStatus) +void +AdrComponent::OnFailedReply(Ptr status, Ptr networkStatus) { - NS_LOG_FUNCTION (this->GetTypeId () << networkStatus); + NS_LOG_FUNCTION(this->GetTypeId() << networkStatus); } -void AdrComponent::AdrImplementation (uint8_t *newDataRate, - uint8_t *newTxPower, - Ptr status) +void +AdrComponent::AdrImplementation(uint8_t* newDataRate, + uint8_t* newTxPower, + Ptr status) { - //Compute the maximum or median SNR, based on the boolean value historyAveraging - double m_SNR = 0; - switch (historyAveraging) + // Compute the maximum or median SNR, based on the boolean value historyAveraging + double m_SNR = 0; + switch (historyAveraging) { case AdrComponent::AVERAGE: - m_SNR = GetAverageSNR (status->GetReceivedPacketList (), - historyRange); - break; + m_SNR = GetAverageSNR(status->GetReceivedPacketList(), historyRange); + break; case AdrComponent::MAXIMUM: - m_SNR = GetMaxSNR (status->GetReceivedPacketList (), - historyRange); - break; + m_SNR = GetMaxSNR(status->GetReceivedPacketList(), historyRange); + break; case AdrComponent::MINIMUM: - m_SNR = GetMinSNR (status->GetReceivedPacketList (), - historyRange); + m_SNR = GetMinSNR(status->GetReceivedPacketList(), historyRange); } - NS_LOG_DEBUG ("m_SNR = " << m_SNR); + NS_LOG_DEBUG("m_SNR = " << m_SNR); - //Get the SF used by the device - uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor (); + // Get the SF used by the device + uint8_t spreadingFactor = status->GetFirstReceiveWindowSpreadingFactor(); - NS_LOG_DEBUG ("SF = " << (unsigned)spreadingFactor); + NS_LOG_DEBUG("SF = " << (unsigned)spreadingFactor); - //Get the device data rate and use it to get the SNR demodulation treshold - double req_SNR = treshold[SfToDr (spreadingFactor)]; + // Get the device data rate and use it to get the SNR demodulation treshold + double req_SNR = treshold[SfToDr(spreadingFactor)]; - NS_LOG_DEBUG ("Required SNR = " << req_SNR); + NS_LOG_DEBUG("Required SNR = " << req_SNR); - //Get the device transmission power (dBm) - double transmissionPower = status->GetMac ()->GetTransmissionPower (); + // Get the device transmission power (dBm) + double transmissionPower = status->GetMac()->GetTransmissionPower(); - NS_LOG_DEBUG ("Transmission Power = " << transmissionPower); + NS_LOG_DEBUG("Transmission Power = " << transmissionPower); - //Compute the SNR margin taking into consideration the SNR of - //previously received packets - double margin_SNR = m_SNR - req_SNR; + // Compute the SNR margin taking into consideration the SNR of + // previously received packets + double margin_SNR = m_SNR - req_SNR; - NS_LOG_DEBUG ("Margin = " << margin_SNR); + NS_LOG_DEBUG("Margin = " << margin_SNR); - //Number of steps to decrement the SF (thereby increasing the Data Rate) - //and the TP. - int steps = std::floor (margin_SNR / 3); + // Number of steps to decrement the SF (thereby increasing the Data Rate) + // and the TP. + int steps = std::floor(margin_SNR / 3); - NS_LOG_DEBUG ("steps = " << steps); + NS_LOG_DEBUG("steps = " << steps); - //If the number of steps is positive (margin_SNR is positive, so its - //decimal value is high) increment the data rate, if there are some - //leftover steps after reaching the maximum possible data rate - //(corresponding to the minimum SF) decrement the transmission power as - //well for the number of steps left. - //If, on the other hand, the number of steps is negative (margin_SNR is - //negative, so its decimal value is low) increase the transmission power - //(note that the SF is not incremented as this particular algorithm - //expects the node itself to raise its SF whenever necessary). - while (steps > 0 && spreadingFactor > min_spreadingFactor) + // If the number of steps is positive (margin_SNR is positive, so its + // decimal value is high) increment the data rate, if there are some + // leftover steps after reaching the maximum possible data rate + //(corresponding to the minimum SF) decrement the transmission power as + // well for the number of steps left. + // If, on the other hand, the number of steps is negative (margin_SNR is + // negative, so its decimal value is low) increase the transmission power + //(note that the SF is not incremented as this particular algorithm + // expects the node itself to raise its SF whenever necessary). + while (steps > 0 && spreadingFactor > min_spreadingFactor) { - spreadingFactor--; - steps--; - NS_LOG_DEBUG ("Decreased SF by 1"); + spreadingFactor--; + steps--; + NS_LOG_DEBUG("Decreased SF by 1"); } - while (steps > 0 && transmissionPower > min_transmissionPower) + while (steps > 0 && transmissionPower > min_transmissionPower) { - transmissionPower -= 2; - steps--; - NS_LOG_DEBUG ("Decreased Ptx by 2"); + transmissionPower -= 2; + steps--; + NS_LOG_DEBUG("Decreased Ptx by 2"); } - while (steps < 0 && transmissionPower < max_transmissionPower) + while (steps < 0 && transmissionPower < max_transmissionPower) { - transmissionPower += 2; - steps++; - NS_LOG_DEBUG ("Increased Ptx by 2"); + transmissionPower += 2; + steps++; + NS_LOG_DEBUG("Increased Ptx by 2"); } - *newDataRate = SfToDr (spreadingFactor); - *newTxPower = transmissionPower; + *newDataRate = SfToDr(spreadingFactor); + *newTxPower = transmissionPower; } -uint8_t AdrComponent::SfToDr (uint8_t sf) +uint8_t +AdrComponent::SfToDr(uint8_t sf) { - switch (sf) + switch (sf) { case 12: - return 0; - break; + return 0; + break; case 11: - return 1; - break; + return 1; + break; case 10: - return 2; - break; + return 2; + break; case 9: - return 3; - break; + return 3; + break; case 8: - return 4; - break; + return 4; + break; default: - return 5; - break; + return 5; + break; } } -double AdrComponent::RxPowerToSNR (double transmissionPower) +double +AdrComponent::RxPowerToSNR(double transmissionPower) { - //The following conversion ignores interfering packets - return transmissionPower + 174 - 10 * log10 (B) - NF; + // The following conversion ignores interfering packets + return transmissionPower + 174 - 10 * log10(B) - NF; } -//Get the maximum received power (it considers the values in dB!) -double AdrComponent::GetMinTxFromGateways (EndDeviceStatus::GatewayList gwList) +// Get the maximum received power (it considers the values in dB!) +double +AdrComponent::GetMinTxFromGateways(EndDeviceStatus::GatewayList gwList) { - EndDeviceStatus::GatewayList::iterator it = gwList.begin (); - double min = it->second.rxPower; + EndDeviceStatus::GatewayList::iterator it = gwList.begin(); + double min = it->second.rxPower; - for (; it != gwList.end (); it++) + for (; it != gwList.end(); it++) { - if (it->second.rxPower < min) + if (it->second.rxPower < min) { - min = it->second.rxPower; + min = it->second.rxPower; } } - return min; + return min; } -//Get the maximum received power (it considers the values in dB!) -double AdrComponent::GetMaxTxFromGateways (EndDeviceStatus::GatewayList gwList) +// Get the maximum received power (it considers the values in dB!) +double +AdrComponent::GetMaxTxFromGateways(EndDeviceStatus::GatewayList gwList) { - EndDeviceStatus::GatewayList::iterator it = gwList.begin (); - double max = it->second.rxPower; + EndDeviceStatus::GatewayList::iterator it = gwList.begin(); + double max = it->second.rxPower; - for (; it != gwList.end (); it++) + for (; it != gwList.end(); it++) { - if (it->second.rxPower > max) + if (it->second.rxPower > max) { - max = it->second.rxPower; + max = it->second.rxPower; } } - return max; + return max; } -//Get the maximum received power -double AdrComponent::GetAverageTxFromGateways (EndDeviceStatus::GatewayList gwList) +// Get the maximum received power +double +AdrComponent::GetAverageTxFromGateways(EndDeviceStatus::GatewayList gwList) { - double sum = 0; + double sum = 0; - for (EndDeviceStatus::GatewayList::iterator it = gwList.begin (); it != gwList.end (); it++) + for (EndDeviceStatus::GatewayList::iterator it = gwList.begin(); it != gwList.end(); it++) { - NS_LOG_DEBUG ("Gateway at " << it->first << " has TP " << it->second.rxPower); - sum += it->second.rxPower; + NS_LOG_DEBUG("Gateway at " << it->first << " has TP " << it->second.rxPower); + sum += it->second.rxPower; } - double average = sum / gwList.size (); + double average = sum / gwList.size(); - NS_LOG_DEBUG ("TP (average) = " << average); + NS_LOG_DEBUG("TP (average) = " << average); - return average; + return average; } double -AdrComponent::GetReceivedPower (EndDeviceStatus::GatewayList gwList) +AdrComponent::GetReceivedPower(EndDeviceStatus::GatewayList gwList) { - switch (tpAveraging) + switch (tpAveraging) { case AdrComponent::AVERAGE: - return GetAverageTxFromGateways (gwList); + return GetAverageTxFromGateways(gwList); case AdrComponent::MAXIMUM: - return GetMaxTxFromGateways (gwList); + return GetMaxTxFromGateways(gwList); case AdrComponent::MINIMUM: - return GetMinTxFromGateways (gwList); + return GetMinTxFromGateways(gwList); default: - return -1; + return -1; } } // TODO Make this more elegant -double AdrComponent::GetMinSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange) +double +AdrComponent::GetMinSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange) { - double m_SNR; + double m_SNR; - //Take elements from the list starting at the end - auto it = packetList.rbegin (); - double min = RxPowerToSNR (GetReceivedPower (it->second.gwList)); + // Take elements from the list starting at the end + auto it = packetList.rbegin(); + double min = RxPowerToSNR(GetReceivedPower(it->second.gwList)); - for (int i = 0; i < historyRange; i++, it++) + for (int i = 0; i < historyRange; i++, it++) { - m_SNR = RxPowerToSNR (GetReceivedPower (it->second.gwList)); + m_SNR = RxPowerToSNR(GetReceivedPower(it->second.gwList)); - NS_LOG_DEBUG ("Received power: " << GetReceivedPower (it->second.gwList)); - NS_LOG_DEBUG ("m_SNR = " << m_SNR); + NS_LOG_DEBUG("Received power: " << GetReceivedPower(it->second.gwList)); + NS_LOG_DEBUG("m_SNR = " << m_SNR); - if (m_SNR < min) + if (m_SNR < min) { - min = m_SNR; + min = m_SNR; } } - NS_LOG_DEBUG ("SNR (min) = " << min); + NS_LOG_DEBUG("SNR (min) = " << min); - return min; + return min; } -double AdrComponent::GetMaxSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange) +double +AdrComponent::GetMaxSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange) { - double m_SNR; + double m_SNR; - //Take elements from the list starting at the end - auto it = packetList.rbegin (); - double max = RxPowerToSNR (GetReceivedPower (it->second.gwList)); + // Take elements from the list starting at the end + auto it = packetList.rbegin(); + double max = RxPowerToSNR(GetReceivedPower(it->second.gwList)); - for (int i = 0; i < historyRange; i++, it++) + for (int i = 0; i < historyRange; i++, it++) { - m_SNR = RxPowerToSNR (GetReceivedPower (it->second.gwList)); + m_SNR = RxPowerToSNR(GetReceivedPower(it->second.gwList)); - NS_LOG_DEBUG ("Received power: " << GetReceivedPower (it->second.gwList)); - NS_LOG_DEBUG ("m_SNR = " << m_SNR); + NS_LOG_DEBUG("Received power: " << GetReceivedPower(it->second.gwList)); + NS_LOG_DEBUG("m_SNR = " << m_SNR); - if (m_SNR > max) + if (m_SNR > max) { - max = m_SNR; + max = m_SNR; } } - NS_LOG_DEBUG ("SNR (max) = " << max); + NS_LOG_DEBUG("SNR (max) = " << max); - return max; + return max; } -double AdrComponent::GetAverageSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange) +double +AdrComponent::GetAverageSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange) { - double sum = 0; - double m_SNR; + double sum = 0; + double m_SNR; - //Take elements from the list starting at the end - auto it = packetList.rbegin (); - for (int i = 0; i < historyRange; i++, it++) + // Take elements from the list starting at the end + auto it = packetList.rbegin(); + for (int i = 0; i < historyRange; i++, it++) { - m_SNR = RxPowerToSNR (GetReceivedPower (it->second.gwList)); + m_SNR = RxPowerToSNR(GetReceivedPower(it->second.gwList)); - NS_LOG_DEBUG ("Received power: " << GetReceivedPower (it->second.gwList)); - NS_LOG_DEBUG ("m_SNR = " << m_SNR); + NS_LOG_DEBUG("Received power: " << GetReceivedPower(it->second.gwList)); + NS_LOG_DEBUG("m_SNR = " << m_SNR); - sum += m_SNR; + sum += m_SNR; } - double average = sum / historyRange; + double average = sum / historyRange; - NS_LOG_DEBUG ("SNR (average) = " << average); + NS_LOG_DEBUG("SNR (average) = " << average); - return average; + return average; } -int AdrComponent::GetTxPowerIndex (int txPower) +int +AdrComponent::GetTxPowerIndex(int txPower) { - if (txPower >= 16) + if (txPower >= 16) { - return 0; + return 0; } - else if (txPower >= 14) + else if (txPower >= 14) { - return 1; + return 1; } - else if (txPower >= 12) + else if (txPower >= 12) { - return 2; + return 2; } - else if (txPower >= 10) + else if (txPower >= 10) { - return 3; + return 3; } - else if (txPower >= 8) + else if (txPower >= 8) { - return 4; + return 4; } - else if (txPower >= 6) + else if (txPower >= 6) { - return 5; + return 5; } - else if (txPower >= 4) + else if (txPower >= 4) { - return 6; + return 6; } - else + else { - return 7; + return 7; } } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/adr-component.h b/model/adr-component.h index 152215e96d..d311f79781 100644 --- a/model/adr-component.h +++ b/model/adr-component.h @@ -21,14 +21,17 @@ #ifndef ADR_COMPONENT_H #define ADR_COMPONENT_H -#include "ns3/object.h" +#include "network-controller-components.h" +#include "network-status.h" + #include "ns3/log.h" +#include "ns3/object.h" #include "ns3/packet.h" -#include "ns3/network-status.h" -#include "ns3/network-controller-components.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ //////////////////////////////////////// // LinkAdrRequest commands management // @@ -36,92 +39,86 @@ namespace lorawan { class AdrComponent : public NetworkControllerComponent { - enum CombiningMethod - { - AVERAGE, - MAXIMUM, - MINIMUM, - }; + enum CombiningMethod + { + AVERAGE, + MAXIMUM, + MINIMUM, + }; + + public: + static TypeId GetTypeId(void); -public: - static TypeId GetTypeId (void); + // Constructor + AdrComponent(); + // Destructor + virtual ~AdrComponent(); - //Constructor - AdrComponent (); - //Destructor - virtual ~AdrComponent (); + void OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus); - void OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus); + void BeforeSendingReply(Ptr status, Ptr networkStatus); - void BeforeSendingReply (Ptr status, - Ptr networkStatus); + void OnFailedReply(Ptr status, Ptr networkStatus); - void OnFailedReply (Ptr status, - Ptr networkStatus); -private: - void AdrImplementation (uint8_t *newDataRate, - uint8_t *newTxPower, - Ptr status); + private: + void AdrImplementation(uint8_t* newDataRate, uint8_t* newTxPower, Ptr status); - uint8_t SfToDr (uint8_t sf); + uint8_t SfToDr(uint8_t sf); - double RxPowerToSNR (double transmissionPower); + double RxPowerToSNR(double transmissionPower); - double GetMinTxFromGateways (EndDeviceStatus::GatewayList gwList); + double GetMinTxFromGateways(EndDeviceStatus::GatewayList gwList); - double GetMaxTxFromGateways (EndDeviceStatus::GatewayList gwList); + double GetMaxTxFromGateways(EndDeviceStatus::GatewayList gwList); - double GetAverageTxFromGateways (EndDeviceStatus::GatewayList gwList); + double GetAverageTxFromGateways(EndDeviceStatus::GatewayList gwList); - double GetReceivedPower (EndDeviceStatus::GatewayList gwList); + double GetReceivedPower(EndDeviceStatus::GatewayList gwList); - double GetMinSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange); + double GetMinSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange); - double GetMaxSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange); + double GetMaxSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange); - double GetAverageSNR (EndDeviceStatus::ReceivedPacketList packetList, - int historyRange); + double GetAverageSNR(EndDeviceStatus::ReceivedPacketList packetList, int historyRange); - int GetTxPowerIndex (int txPower); + int GetTxPowerIndex(int txPower); - //TX power from gateways policy - enum CombiningMethod tpAveraging; + // TX power from gateways policy + enum CombiningMethod tpAveraging; - //Number of previous packets to consider - int historyRange; + // Number of previous packets to consider + int historyRange; - //Received SNR history policy - enum CombiningMethod historyAveraging; + // Received SNR history policy + enum CombiningMethod historyAveraging; - //SF lower limit - const int min_spreadingFactor = 7; + // SF lower limit + const int min_spreadingFactor = 7; - //Minimum transmission power (dBm) (Europe) - const int min_transmissionPower = 2; + // Minimum transmission power (dBm) (Europe) + const int min_transmissionPower = 2; - //Maximum transmission power (dBm) (Europe) - const int max_transmissionPower = 14; + // Maximum transmission power (dBm) (Europe) + const int max_transmissionPower = 14; - //Device specific SNR margin (dB) - // const int offset = 10; + // Device specific SNR margin (dB) + // const int offset = 10; - //Bandwidth (Hz) - const int B = 125000; + // Bandwidth (Hz) + const int B = 125000; - //Noise Figure (dB) - const int NF = 6; + // Noise Figure (dB) + const int NF = 6; - //Vector containing the required SNR for the 6 allowed SF levels - //ranging from 7 to 12 (the SNR values are in dB). - double treshold[6] = {-20.0, -17.5, -15.0, -12.5, -10.0, -7.5}; + // Vector containing the required SNR for the 6 allowed SF levels + // ranging from 7 to 12 (the SNR values are in dB). + double treshold[6] = {-20.0, -17.5, -15.0, -12.5, -10.0, -7.5}; - bool m_toggleTxPower; + bool m_toggleTxPower; }; -} -} +} // namespace lorawan +} // namespace ns3 #endif diff --git a/model/building-penetration-loss.cc b/model/building-penetration-loss.cc index ede4c92375..f36667442d 100644 --- a/model/building-penetration-loss.cc +++ b/model/building-penetration-loss.cc @@ -16,224 +16,222 @@ * Author: Davide Magrin */ -#include "ns3/building-penetration-loss.h" -#include "ns3/mobility-building-info.h" +#include "building-penetration-loss.h" + #include "ns3/double.h" #include "ns3/log.h" +#include "ns3/mobility-building-info.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("BuildingPenetrationLoss"); +NS_LOG_COMPONENT_DEFINE("BuildingPenetrationLoss"); -NS_OBJECT_ENSURE_REGISTERED (BuildingPenetrationLoss); +NS_OBJECT_ENSURE_REGISTERED(BuildingPenetrationLoss); TypeId -BuildingPenetrationLoss::GetTypeId (void) +BuildingPenetrationLoss::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::BuildingPenetrationLoss") - .SetParent () - .SetGroupName ("Lora") - .AddConstructor () - ; - return tid; + static TypeId tid = TypeId("ns3::BuildingPenetrationLoss") + .SetParent() + .SetGroupName("Lora") + .AddConstructor(); + return tid; } -BuildingPenetrationLoss::BuildingPenetrationLoss () +BuildingPenetrationLoss::BuildingPenetrationLoss() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Initialize the random variable - m_uniformRV = CreateObject (); + // Initialize the random variable + m_uniformRV = CreateObject(); } -BuildingPenetrationLoss::~BuildingPenetrationLoss () +BuildingPenetrationLoss::~BuildingPenetrationLoss() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } double -BuildingPenetrationLoss::DoCalcRxPower (double txPowerDbm, - Ptr a, - Ptr b) const +BuildingPenetrationLoss::DoCalcRxPower(double txPowerDbm, + Ptr a, + Ptr b) const { - NS_LOG_FUNCTION (this << txPowerDbm << a << b); + NS_LOG_FUNCTION(this << txPowerDbm << a << b); - Ptr a1 = a->GetObject (); - Ptr b1 = b->GetObject (); + Ptr a1 = a->GetObject(); + Ptr b1 = b->GetObject(); - // These are the components of the loss due to building penetration - double externalWallLoss = 0; - double tor1 = 0; - double tor3 = 0; - double gfh = 0; + // These are the components of the loss due to building penetration + double externalWallLoss = 0; + double tor1 = 0; + double tor3 = 0; + double gfh = 0; - // Go through various cases in which a and b are indoors or outdoors - if ((b1->IsIndoor () && !a1->IsIndoor ())) + // Go through various cases in which a and b are indoors or outdoors + if ((b1->IsIndoor() && !a1->IsIndoor())) { - NS_LOG_INFO ("Tx is outdoors and Rx is indoors"); - - externalWallLoss = GetWallLoss (b); // External wall loss due to b - tor1 = GetTor1 (b); // Internal wall loss due to b - tor3 = 0.6 * m_uniformRV->GetValue (0, 15); - gfh = 0; + NS_LOG_INFO("Tx is outdoors and Rx is indoors"); + externalWallLoss = GetWallLoss(b); // External wall loss due to b + tor1 = GetTor1(b); // Internal wall loss due to b + tor3 = 0.6 * m_uniformRV->GetValue(0, 15); + gfh = 0; } - else if ((!b1->IsIndoor () && a1->IsIndoor ())) + else if ((!b1->IsIndoor() && a1->IsIndoor())) { - NS_LOG_INFO ("Rx is outdoors and Tx is indoors"); - - // These are the components of the loss due to building penetration - externalWallLoss = GetWallLoss (a); - tor1 = GetTor1 (a); - tor3 = 0.6 * m_uniformRV->GetValue (0, 15); - gfh = 0; + NS_LOG_INFO("Rx is outdoors and Tx is indoors"); + // These are the components of the loss due to building penetration + externalWallLoss = GetWallLoss(a); + tor1 = GetTor1(a); + tor3 = 0.6 * m_uniformRV->GetValue(0, 15); + gfh = 0; } - else if (!a1->IsIndoor ()&& !b1->IsIndoor ()) + else if (!a1->IsIndoor() && !b1->IsIndoor()) { - NS_LOG_DEBUG ("No penetration loss since both devices are outside"); + NS_LOG_DEBUG("No penetration loss since both devices are outside"); } - else if (a1->IsIndoor ()&& b1->IsIndoor ()) + else if (a1->IsIndoor() && b1->IsIndoor()) { - // They are in the same building - if (a1->GetBuilding () == b1->GetBuilding ()) + // They are in the same building + if (a1->GetBuilding() == b1->GetBuilding()) { - NS_LOG_INFO ("Devices are in the same building"); - // Only internal wall loss - tor1 = GetTor1 (b); - tor3 = 0.6 * m_uniformRV->GetValue (0, 15); + NS_LOG_INFO("Devices are in the same building"); + // Only internal wall loss + tor1 = GetTor1(b); + tor3 = 0.6 * m_uniformRV->GetValue(0, 15); } - // They are in different buildings - else + // They are in different buildings + else { - // These are the components of the loss due to building penetration - externalWallLoss = GetWallLoss (b) + GetWallLoss (a); - tor1 = GetTor1 (b) + GetTor1 (a); - tor3 = 0.6 * m_uniformRV->GetValue (0, 15); - gfh = 0; + // These are the components of the loss due to building penetration + externalWallLoss = GetWallLoss(b) + GetWallLoss(a); + tor1 = GetTor1(b) + GetTor1(a); + tor3 = 0.6 * m_uniformRV->GetValue(0, 15); + gfh = 0; } } - NS_LOG_DEBUG ("Building penetration loss:" << - " externalWallLoss = " << externalWallLoss << - ", tor1 = " << tor1 << - ", tor3 = " << tor3 << - ", GFH = " << gfh); + NS_LOG_DEBUG("Building penetration loss:" + << " externalWallLoss = " << externalWallLoss << ", tor1 = " << tor1 + << ", tor3 = " << tor3 << ", GFH = " << gfh); - // Put together all the pieces - double loss = externalWallLoss + std::max (tor1, tor3) - gfh; + // Put together all the pieces + double loss = externalWallLoss + std::max(tor1, tor3) - gfh; - NS_LOG_DEBUG ("Total loss due to building penetration: " << loss); + NS_LOG_DEBUG("Total loss due to building penetration: " << loss); - return txPowerDbm - loss; + return txPowerDbm - loss; } int64_t -BuildingPenetrationLoss::DoAssignStreams (int64_t stream) +BuildingPenetrationLoss::DoAssignStreams(int64_t stream) { - m_uniformRV->SetStream (stream); - return 1; + m_uniformRV->SetStream(stream); + return 1; } int -BuildingPenetrationLoss::GetPValue (void) const +BuildingPenetrationLoss::GetPValue(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // We need to decide on the p value to return - double random = m_uniformRV->GetValue (0.0, 1.0); + // We need to decide on the p value to return + double random = m_uniformRV->GetValue(0.0, 1.0); - // Distribution is specified in TR 45.820, page 482, first scenario - if (random < 0.2833) + // Distribution is specified in TR 45.820, page 482, first scenario + if (random < 0.2833) { - return 0; + return 0; } - else if (random < 0.566) + else if (random < 0.566) { - return 1; + return 1; } - else if (random < 0.85) + else if (random < 0.85) { - return 2; + return 2; } - else + else { - return 3; + return 3; } } int -BuildingPenetrationLoss::GetWallLossValue (void) const +BuildingPenetrationLoss::GetWallLossValue(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // We need to decide on the random value to return - double random = m_uniformRV->GetValue (0.0, 1.0); + // We need to decide on the random value to return + double random = m_uniformRV->GetValue(0.0, 1.0); - // Distribution is specified in TR 45.820, page 482, first scenario - if (random < 0.25) + // Distribution is specified in TR 45.820, page 482, first scenario + if (random < 0.25) { - return 0; + return 0; } - else if (random < 0.9) + else if (random < 0.9) { - return 1; + return 1; } - else + else { - return 2; + return 2; } } double -BuildingPenetrationLoss::GetWallLoss (Ptr b) const +BuildingPenetrationLoss::GetWallLoss(Ptr b) const { - NS_LOG_FUNCTION (this << b); + NS_LOG_FUNCTION(this << b); - std::map, int>::const_iterator it; + std::map, int>::const_iterator it; - // Check whether the b device already has a wall loss value - it = m_wallLossMap.find (b); - if (it == m_wallLossMap.end ()) + // Check whether the b device already has a wall loss value + it = m_wallLossMap.find(b); + if (it == m_wallLossMap.end()) { - // Create a random value and insert it on the map - m_wallLossMap[b] = GetWallLossValue (); - NS_LOG_DEBUG ("Inserted a new wall loss value: " << - m_wallLossMap.find (b)->second); + // Create a random value and insert it on the map + m_wallLossMap[b] = GetWallLossValue(); + NS_LOG_DEBUG("Inserted a new wall loss value: " << m_wallLossMap.find(b)->second); } - switch (m_wallLossMap.find (b)->second) + switch (m_wallLossMap.find(b)->second) { case 0: - return m_uniformRV->GetValue (4, 11); + return m_uniformRV->GetValue(4, 11); case 1: - return m_uniformRV->GetValue (11, 19); + return m_uniformRV->GetValue(11, 19); case 2: - return m_uniformRV->GetValue (19, 23); + return m_uniformRV->GetValue(19, 23); } - // Case in which something goes wrong - return 0; + // Case in which something goes wrong + return 0; } double -BuildingPenetrationLoss::GetTor1 (Ptr b) const +BuildingPenetrationLoss::GetTor1(Ptr b) const { - NS_LOG_FUNCTION (this << b); + NS_LOG_FUNCTION(this << b); - std::map, int>::const_iterator it; + std::map, int>::const_iterator it; - // Check whether the b device already has a p value - it = m_pMap.find (b); - if (it == m_pMap.end ()) + // Check whether the b device already has a p value + it = m_pMap.find(b); + if (it == m_pMap.end()) { - // Create a random p value and insert it on the map - m_pMap[b] = GetPValue (); - NS_LOG_DEBUG ("Inserted a new p value: " << m_pMap.find (b)->second); + // Create a random p value and insert it on the map + m_pMap[b] = GetPValue(); + NS_LOG_DEBUG("Inserted a new p value: " << m_pMap.find(b)->second); } - return m_uniformRV->GetValue (4, 10) * m_pMap.find (b)->second; -} -} + return m_uniformRV->GetValue(4, 10) * m_pMap.find(b)->second; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/building-penetration-loss.h b/model/building-penetration-loss.h index a6a849bf93..0d7182fcb4 100644 --- a/model/building-penetration-loss.h +++ b/model/building-penetration-loss.h @@ -19,82 +19,84 @@ #ifndef BUILDING_PENETRATION_LOSS_H #define BUILDING_PENETRATION_LOSS_H -#include "ns3/propagation-loss-model.h" #include "ns3/mobility-model.h" -#include "ns3/vector.h" +#include "ns3/propagation-loss-model.h" #include "ns3/random-variable-stream.h" +#include "ns3/vector.h" -namespace ns3 { +namespace ns3 +{ class MobilityModel; -namespace lorawan { +namespace lorawan +{ /** * A class implementing the TR 45.820 model for building losses */ class BuildingPenetrationLoss : public PropagationLossModel { -public: - static TypeId GetTypeId (void); - - BuildingPenetrationLoss (); - - ~BuildingPenetrationLoss (); - -private: - /** - * Perform the computation of the received power according to the current - * model. - */ - virtual double DoCalcRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; - - virtual int64_t DoAssignStreams (int64_t stream); - - /** - * Generate a random p value. - * The distribution of the returned value is as specified in TR 45.820. - * \returns A value in the 0-3 range. - */ - int GetPValue (void) const; - - /** - * Get a value to compute the wall loss. - * The distribution of the returned value is as specified in TR 45.820. - * \returns A value in the 0-2 range. - */ - int GetWallLossValue (void) const; - - /** - * Compute the wall loss associated to this mobility model - * \param b The mobility model associated to the node whose wall loss we need - * to compute. - * \returns The power loss due to external walls. - */ - double GetWallLoss (Ptr b) const; - - /** - * Get the Tor1 value used in the TR 45.820 standard to account for internal - * wall loss. - * \param b The mobility model of the node we want to compute the value for. - * \returns The tor1 value. - */ - double GetTor1 (Ptr b) const; - - Ptr m_uniformRV; //!< An uniform RV - - /** - * A map linking each mobility model to a p value - */ - mutable std::map, int> m_pMap; - - /** - * A map linking each mobility model to a value deciding its external wall - * loss. - */ - mutable std::map, int> m_wallLossMap; + public: + static TypeId GetTypeId(void); + + BuildingPenetrationLoss(); + + ~BuildingPenetrationLoss(); + + private: + /** + * Perform the computation of the received power according to the current + * model. + */ + virtual double DoCalcRxPower(double txPowerDbm, + Ptr a, + Ptr b) const; + + virtual int64_t DoAssignStreams(int64_t stream); + + /** + * Generate a random p value. + * The distribution of the returned value is as specified in TR 45.820. + * \returns A value in the 0-3 range. + */ + int GetPValue(void) const; + + /** + * Get a value to compute the wall loss. + * The distribution of the returned value is as specified in TR 45.820. + * \returns A value in the 0-2 range. + */ + int GetWallLossValue(void) const; + + /** + * Compute the wall loss associated to this mobility model + * \param b The mobility model associated to the node whose wall loss we need + * to compute. + * \returns The power loss due to external walls. + */ + double GetWallLoss(Ptr b) const; + + /** + * Get the Tor1 value used in the TR 45.820 standard to account for internal + * wall loss. + * \param b The mobility model of the node we want to compute the value for. + * \returns The tor1 value. + */ + double GetTor1(Ptr b) const; + + Ptr m_uniformRV; //!< An uniform RV + + /** + * A map linking each mobility model to a p value + */ + mutable std::map, int> m_pMap; + + /** + * A map linking each mobility model to a value deciding its external wall + * loss. + */ + mutable std::map, int> m_wallLossMap; }; -} -} +} // namespace lorawan +} // namespace ns3 #endif diff --git a/model/class-a-end-device-lorawan-mac.cc b/model/class-a-end-device-lorawan-mac.cc index 7b958375fe..2dd1faf63d 100644 --- a/model/class-a-end-device-lorawan-mac.cc +++ b/model/class-a-end-device-lorawan-mac.cc @@ -22,50 +22,55 @@ * qiuyukang */ -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/end-device-lorawan-mac.h" -#include "ns3/end-device-lora-phy.h" +#include "class-a-end-device-lorawan-mac.h" + +#include "end-device-lora-phy.h" +#include "end-device-lorawan-mac.h" + #include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("ClassAEndDeviceLorawanMac"); +NS_LOG_COMPONENT_DEFINE("ClassAEndDeviceLorawanMac"); -NS_OBJECT_ENSURE_REGISTERED (ClassAEndDeviceLorawanMac); +NS_OBJECT_ENSURE_REGISTERED(ClassAEndDeviceLorawanMac); TypeId -ClassAEndDeviceLorawanMac::GetTypeId (void) +ClassAEndDeviceLorawanMac::GetTypeId(void) { -static TypeId tid = TypeId ("ns3::ClassAEndDeviceLorawanMac") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor (); -return tid; + static TypeId tid = TypeId("ns3::ClassAEndDeviceLorawanMac") + .SetParent() + .SetGroupName("lorawan") + .AddConstructor(); + return tid; } -ClassAEndDeviceLorawanMac::ClassAEndDeviceLorawanMac () : - // LoraWAN default - m_receiveDelay1 (Seconds (1)), - // LoraWAN default - m_receiveDelay2 (Seconds (2)), - m_rx1DrOffset (0) +ClassAEndDeviceLorawanMac::ClassAEndDeviceLorawanMac() + : // LoraWAN default + m_receiveDelay1(Seconds(1)), + // LoraWAN default + m_receiveDelay2(Seconds(2)), + m_rx1DrOffset(0) { - NS_LOG_FUNCTION (this); - - // Void the two receiveWindow events - m_closeFirstWindow = EventId (); - m_closeFirstWindow.Cancel (); - m_closeSecondWindow = EventId (); - m_closeSecondWindow.Cancel (); - m_secondReceiveWindow = EventId (); - m_secondReceiveWindow.Cancel (); + NS_LOG_FUNCTION(this); + + // Void the two receiveWindow events + m_closeFirstWindow = EventId(); + m_closeFirstWindow.Cancel(); + m_closeSecondWindow = EventId(); + m_closeSecondWindow.Cancel(); + m_secondReceiveWindow = EventId(); + m_secondReceiveWindow.Cancel(); } -ClassAEndDeviceLorawanMac::~ClassAEndDeviceLorawanMac () +ClassAEndDeviceLorawanMac::~ClassAEndDeviceLorawanMac() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } ///////////////////// @@ -73,371 +78,380 @@ ClassAEndDeviceLorawanMac::~ClassAEndDeviceLorawanMac () ///////////////////// void -ClassAEndDeviceLorawanMac::SendToPhy (Ptr packetToSend) +ClassAEndDeviceLorawanMac::SendToPhy(Ptr packetToSend) { - ///////////////////////////////////////////////////////// - // Add headers, prepare TX parameters and send the packet - ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // Add headers, prepare TX parameters and send the packet + ///////////////////////////////////////////////////////// - NS_LOG_DEBUG ("PacketToSend: " << packetToSend); + NS_LOG_DEBUG("PacketToSend: " << packetToSend); - // Data Rate Adaptation as in LoRaWAN specification, V1.0.2 (2016) - if (m_enableDRAdapt && (m_dataRate > 0) - && (m_retxParams.retxLeft < m_maxNumbTx) - && (m_retxParams.retxLeft % 2 == 0) ) + // Data Rate Adaptation as in LoRaWAN specification, V1.0.2 (2016) + if (m_enableDRAdapt && (m_dataRate > 0) && (m_retxParams.retxLeft < m_maxNumbTx) && + (m_retxParams.retxLeft % 2 == 0)) { - m_txPower = 14; // Reset transmission power - m_dataRate = m_dataRate - 1; + m_txPower = 14; // Reset transmission power + m_dataRate = m_dataRate - 1; } - // Craft LoraTxParameters object - LoraTxParameters params; - params.sf = GetSfFromDataRate (m_dataRate); - params.headerDisabled = m_headerDisabled; - params.codingRate = m_codingRate; - params.bandwidthHz = GetBandwidthFromDataRate (m_dataRate); - params.nPreamble = m_nPreambleSymbols; - params.crcEnabled = 1; - params.lowDataRateOptimizationEnabled = LoraPhy::GetTSym (params) > MilliSeconds (16) ? true : false; - - // Wake up PHY layer and directly send the packet + // Craft LoraTxParameters object + LoraTxParameters params; + params.sf = GetSfFromDataRate(m_dataRate); + params.headerDisabled = m_headerDisabled; + params.codingRate = m_codingRate; + params.bandwidthHz = GetBandwidthFromDataRate(m_dataRate); + params.nPreamble = m_nPreambleSymbols; + params.crcEnabled = 1; + params.lowDataRateOptimizationEnabled = + LoraPhy::GetTSym(params) > MilliSeconds(16) ? true : false; - Ptr txChannel = GetChannelForTx (); + // Wake up PHY layer and directly send the packet - NS_LOG_DEBUG ("PacketToSend: " << packetToSend); - m_phy->Send (packetToSend, params, txChannel->GetFrequency (), m_txPower); + Ptr txChannel = GetChannelForTx(); - ////////////////////////////////////////////// - // Register packet transmission for duty cycle - ////////////////////////////////////////////// + NS_LOG_DEBUG("PacketToSend: " << packetToSend); + m_phy->Send(packetToSend, params, txChannel->GetFrequency(), m_txPower); - // Compute packet duration - Time duration = m_phy->GetOnAirTime (packetToSend, params); + ////////////////////////////////////////////// + // Register packet transmission for duty cycle + ////////////////////////////////////////////// - // Register the sent packet into the DutyCycleHelper - m_channelHelper.AddEvent (duration, txChannel); + // Compute packet duration + Time duration = m_phy->GetOnAirTime(packetToSend, params); - ////////////////////////////// - // Prepare for the downlink // - ////////////////////////////// + // Register the sent packet into the DutyCycleHelper + m_channelHelper.AddEvent(duration, txChannel); - // Switch the PHY to the channel so that it will listen here for downlink - m_phy->GetObject ()->SetFrequency (txChannel->GetFrequency ()); + ////////////////////////////// + // Prepare for the downlink // + ////////////////////////////// - // Instruct the PHY on the right Spreading Factor to listen for during the window - // create a SetReplyDataRate function? - uint8_t replyDataRate = GetFirstReceiveWindowDataRate (); - NS_LOG_DEBUG ("m_dataRate: " << unsigned (m_dataRate) << - ", m_rx1DrOffset: " << unsigned (m_rx1DrOffset) << - ", replyDataRate: " << unsigned (replyDataRate) << "."); + // Switch the PHY to the channel so that it will listen here for downlink + m_phy->GetObject()->SetFrequency(txChannel->GetFrequency()); - m_phy->GetObject ()->SetSpreadingFactor - (GetSfFromDataRate (replyDataRate)); + // Instruct the PHY on the right Spreading Factor to listen for during the window + // create a SetReplyDataRate function? + uint8_t replyDataRate = GetFirstReceiveWindowDataRate(); + NS_LOG_DEBUG("m_dataRate: " << unsigned(m_dataRate) + << ", m_rx1DrOffset: " << unsigned(m_rx1DrOffset) + << ", replyDataRate: " << unsigned(replyDataRate) << "."); + m_phy->GetObject()->SetSpreadingFactor(GetSfFromDataRate(replyDataRate)); } ////////////////////////// // Receiving methods // ////////////////////////// void -ClassAEndDeviceLorawanMac::Receive (Ptr packet) +ClassAEndDeviceLorawanMac::Receive(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // Work on a copy of the packet - Ptr packetCopy = packet->Copy (); + // Work on a copy of the packet + Ptr packetCopy = packet->Copy(); - // Remove the Mac Header to get some information - LorawanMacHeader mHdr; - packetCopy->RemoveHeader (mHdr); + // Remove the Mac Header to get some information + LorawanMacHeader mHdr; + packetCopy->RemoveHeader(mHdr); - NS_LOG_DEBUG ("Mac Header: " << mHdr); + NS_LOG_DEBUG("Mac Header: " << mHdr); - // Only keep analyzing the packet if it's downlink - if (!mHdr.IsUplink ()) + // Only keep analyzing the packet if it's downlink + if (!mHdr.IsUplink()) { - NS_LOG_INFO ("Found a downlink packet."); + NS_LOG_INFO("Found a downlink packet."); - // Remove the Frame Header - LoraFrameHeader fHdr; - fHdr.SetAsDownlink (); - packetCopy->RemoveHeader (fHdr); + // Remove the Frame Header + LoraFrameHeader fHdr; + fHdr.SetAsDownlink(); + packetCopy->RemoveHeader(fHdr); - NS_LOG_DEBUG ("Frame Header: " << fHdr); + NS_LOG_DEBUG("Frame Header: " << fHdr); - // Determine whether this packet is for us - bool messageForUs = (m_address == fHdr.GetAddress ()); + // Determine whether this packet is for us + bool messageForUs = (m_address == fHdr.GetAddress()); - if (messageForUs) + if (messageForUs) { - NS_LOG_INFO ("The message is for us!"); - - // If it exists, cancel the second receive window event - // THIS WILL BE GetReceiveWindow() - Simulator::Cancel (m_secondReceiveWindow); + NS_LOG_INFO("The message is for us!"); + // If it exists, cancel the second receive window event + // THIS WILL BE GetReceiveWindow() + Simulator::Cancel(m_secondReceiveWindow); - // Parse the MAC commands - ParseCommands (fHdr); + // Parse the MAC commands + ParseCommands(fHdr); - // TODO Pass the packet up to the NetDevice + // TODO Pass the packet up to the NetDevice - - // Call the trace source - m_receivedPacket (packet); + // Call the trace source + m_receivedPacket(packet); } - else + else { - NS_LOG_DEBUG ("The message is intended for another recipient."); - - // In this case, we are either receiving in the first receive window - // and finishing reception inside the second one, or receiving a - // packet in the second receive window and finding out, after the - // fact, that the packet is not for us. In either case, if we no - // longer have any retransmissions left, we declare failure. - if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired ()) + NS_LOG_DEBUG("The message is intended for another recipient."); + + // In this case, we are either receiving in the first receive window + // and finishing reception inside the second one, or receiving a + // packet in the second receive window and finding out, after the + // fact, that the packet is not for us. In either case, if we no + // longer have any retransmissions left, we declare failure. + if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired()) { - if (m_retxParams.retxLeft == 0) + if (m_retxParams.retxLeft == 0) { - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, false, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG ("Failure: no more retransmissions left. Used " << unsigned(txs) << " transmissions."); - - // Reset retransmission parameters - resetRetransmissionParameters (); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, + false, + m_retxParams.firstAttempt, + m_retxParams.packet); + NS_LOG_DEBUG("Failure: no more retransmissions left. Used " + << unsigned(txs) << " transmissions."); + + // Reset retransmission parameters + resetRetransmissionParameters(); } - else // Reschedule + else // Reschedule { - this->Send (m_retxParams.packet); - NS_LOG_INFO ("We have " << unsigned(m_retxParams.retxLeft) << " retransmissions left: rescheduling transmission."); + this->Send(m_retxParams.packet); + NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft) + << " retransmissions left: rescheduling transmission."); } } } } - else if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired ()) + else if (m_retxParams.waitingAck && m_secondReceiveWindow.IsExpired()) { - NS_LOG_INFO ("The packet we are receiving is in uplink."); - if (m_retxParams.retxLeft > 0) + NS_LOG_INFO("The packet we are receiving is in uplink."); + if (m_retxParams.retxLeft > 0) { - this->Send (m_retxParams.packet); - NS_LOG_INFO ("We have " << unsigned(m_retxParams.retxLeft) << " retransmissions left: rescheduling transmission."); + this->Send(m_retxParams.packet); + NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft) + << " retransmissions left: rescheduling transmission."); } - else + else { - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, false, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG ("Failure: no more retransmissions left. Used " << unsigned(txs) << " transmissions."); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs) + << " transmissions."); - // Reset retransmission parameters - resetRetransmissionParameters (); + // Reset retransmission parameters + resetRetransmissionParameters(); } } - m_phy->GetObject ()->SwitchToSleep (); + m_phy->GetObject()->SwitchToSleep(); } void -ClassAEndDeviceLorawanMac::FailedReception (Ptr packet) +ClassAEndDeviceLorawanMac::FailedReception(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // Switch to sleep after a failed reception - m_phy->GetObject ()->SwitchToSleep (); + // Switch to sleep after a failed reception + m_phy->GetObject()->SwitchToSleep(); - if (m_secondReceiveWindow.IsExpired () && m_retxParams.waitingAck) + if (m_secondReceiveWindow.IsExpired() && m_retxParams.waitingAck) { - if (m_retxParams.retxLeft > 0) + if (m_retxParams.retxLeft > 0) { - this->Send (m_retxParams.packet); - NS_LOG_INFO ("We have " << unsigned(m_retxParams.retxLeft) << " retransmissions left: rescheduling transmission."); + this->Send(m_retxParams.packet); + NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft) + << " retransmissions left: rescheduling transmission."); } - else + else { - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, false, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG ("Failure: no more retransmissions left. Used " << unsigned(txs) << " transmissions."); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs) + << " transmissions."); - // Reset retransmission parameters - resetRetransmissionParameters (); + // Reset retransmission parameters + resetRetransmissionParameters(); } } } void -ClassAEndDeviceLorawanMac::TxFinished (Ptr packet) +ClassAEndDeviceLorawanMac::TxFinished(Ptr packet) { - NS_LOG_FUNCTION_NOARGS (); - - // Schedule the opening of the first receive window - Simulator::Schedule (m_receiveDelay1, - &ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow, this); - - // Schedule the opening of the second receive window - m_secondReceiveWindow = Simulator::Schedule (m_receiveDelay2, - &ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow, - this); - // // Schedule the opening of the first receive window - // Simulator::Schedule (m_receiveDelay1, - // &ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow, this); - // - // // Schedule the opening of the second receive window - // m_secondReceiveWindow = Simulator::Schedule (m_receiveDelay2, - // &ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow, - // this); - - // Switch the PHY to sleep - m_phy->GetObject ()->SwitchToSleep (); + NS_LOG_FUNCTION_NOARGS(); + + // Schedule the opening of the first receive window + Simulator::Schedule(m_receiveDelay1, &ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow, this); + + // Schedule the opening of the second receive window + m_secondReceiveWindow = Simulator::Schedule(m_receiveDelay2, + &ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow, + this); + // // Schedule the opening of the first receive window + // Simulator::Schedule (m_receiveDelay1, + // &ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow, this); + // + // // Schedule the opening of the second receive window + // m_secondReceiveWindow = Simulator::Schedule (m_receiveDelay2, + // &ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow, + // this); + + // Switch the PHY to sleep + m_phy->GetObject()->SwitchToSleep(); } void -ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow (void) +ClassAEndDeviceLorawanMac::OpenFirstReceiveWindow(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Set Phy in Standby mode - m_phy->GetObject ()->SwitchToStandby (); + // Set Phy in Standby mode + m_phy->GetObject()->SwitchToStandby(); - //Calculate the duration of a single symbol for the first receive window DR - double tSym = pow (2, GetSfFromDataRate (GetFirstReceiveWindowDataRate ())) / GetBandwidthFromDataRate ( GetFirstReceiveWindowDataRate ()); - - // Schedule return to sleep after "at least the time required by the end - // device's radio transceiver to effectively detect a downlink preamble" - // (LoraWAN specification) - m_closeFirstWindow = Simulator::Schedule (Seconds (m_receiveWindowDurationInSymbols*tSym), - &ClassAEndDeviceLorawanMac::CloseFirstReceiveWindow, this); //m_receiveWindowDuration + // Calculate the duration of a single symbol for the first receive window DR + double tSym = pow(2, GetSfFromDataRate(GetFirstReceiveWindowDataRate())) / + GetBandwidthFromDataRate(GetFirstReceiveWindowDataRate()); + // Schedule return to sleep after "at least the time required by the end + // device's radio transceiver to effectively detect a downlink preamble" + // (LoraWAN specification) + m_closeFirstWindow = Simulator::Schedule(Seconds(m_receiveWindowDurationInSymbols * tSym), + &ClassAEndDeviceLorawanMac::CloseFirstReceiveWindow, + this); // m_receiveWindowDuration } void -ClassAEndDeviceLorawanMac::CloseFirstReceiveWindow (void) +ClassAEndDeviceLorawanMac::CloseFirstReceiveWindow(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - Ptr phy = m_phy->GetObject (); + Ptr phy = m_phy->GetObject(); - // Check the Phy layer's state: - // - RX -> We are receiving a preamble. - // - STANDBY -> Nothing was received. - // - SLEEP -> We have received a packet. - // We should never be in TX or SLEEP mode at this point - switch (phy->GetState ()) + // Check the Phy layer's state: + // - RX -> We are receiving a preamble. + // - STANDBY -> Nothing was received. + // - SLEEP -> We have received a packet. + // We should never be in TX or SLEEP mode at this point + switch (phy->GetState()) { case EndDeviceLoraPhy::TX: - NS_ABORT_MSG ("PHY was in TX mode when attempting to " << - "close a receive window."); - break; + NS_ABORT_MSG("PHY was in TX mode when attempting to " + << "close a receive window."); + break; case EndDeviceLoraPhy::RX: - // PHY is receiving: let it finish. The Receive method will switch it back to SLEEP. - break; + // PHY is receiving: let it finish. The Receive method will switch it back to SLEEP. + break; case EndDeviceLoraPhy::SLEEP: - // PHY has received, and the MAC's Receive already put the device to sleep - break; + // PHY has received, and the MAC's Receive already put the device to sleep + break; case EndDeviceLoraPhy::STANDBY: - // Turn PHY layer to SLEEP - phy->SwitchToSleep (); - break; + // Turn PHY layer to SLEEP + phy->SwitchToSleep(); + break; } } void -ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow (void) +ClassAEndDeviceLorawanMac::OpenSecondReceiveWindow(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Check for receiver status: if it's locked on a packet, don't open this - // window at all. - if (m_phy->GetObject ()->GetState () == EndDeviceLoraPhy::RX) + // Check for receiver status: if it's locked on a packet, don't open this + // window at all. + if (m_phy->GetObject()->GetState() == EndDeviceLoraPhy::RX) { - NS_LOG_INFO ("Won't open second receive window since we are in RX mode."); + NS_LOG_INFO("Won't open second receive window since we are in RX mode."); - return; + return; } - // Set Phy in Standby mode - m_phy->GetObject ()->SwitchToStandby (); - - // Switch to appropriate channel and data rate - NS_LOG_INFO ("Using parameters: " << m_secondReceiveWindowFrequency << "Hz, DR" - << unsigned(m_secondReceiveWindowDataRate)); + // Set Phy in Standby mode + m_phy->GetObject()->SwitchToStandby(); - m_phy->GetObject ()->SetFrequency - (m_secondReceiveWindowFrequency); - m_phy->GetObject ()->SetSpreadingFactor (GetSfFromDataRate - (m_secondReceiveWindowDataRate)); + // Switch to appropriate channel and data rate + NS_LOG_INFO("Using parameters: " << m_secondReceiveWindowFrequency << "Hz, DR" + << unsigned(m_secondReceiveWindowDataRate)); - //Calculate the duration of a single symbol for the second receive window DR - double tSym = pow (2, GetSfFromDataRate (GetSecondReceiveWindowDataRate ())) / GetBandwidthFromDataRate ( GetSecondReceiveWindowDataRate ()); + m_phy->GetObject()->SetFrequency(m_secondReceiveWindowFrequency); + m_phy->GetObject()->SetSpreadingFactor( + GetSfFromDataRate(m_secondReceiveWindowDataRate)); - // Schedule return to sleep after "at least the time required by the end - // device's radio transceiver to effectively detect a downlink preamble" - // (LoraWAN specification) - m_closeSecondWindow = Simulator::Schedule (Seconds (m_receiveWindowDurationInSymbols*tSym), - &ClassAEndDeviceLorawanMac::CloseSecondReceiveWindow, this); + // Calculate the duration of a single symbol for the second receive window DR + double tSym = pow(2, GetSfFromDataRate(GetSecondReceiveWindowDataRate())) / + GetBandwidthFromDataRate(GetSecondReceiveWindowDataRate()); + // Schedule return to sleep after "at least the time required by the end + // device's radio transceiver to effectively detect a downlink preamble" + // (LoraWAN specification) + m_closeSecondWindow = Simulator::Schedule(Seconds(m_receiveWindowDurationInSymbols * tSym), + &ClassAEndDeviceLorawanMac::CloseSecondReceiveWindow, + this); } void -ClassAEndDeviceLorawanMac::CloseSecondReceiveWindow (void) +ClassAEndDeviceLorawanMac::CloseSecondReceiveWindow(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - Ptr phy = m_phy->GetObject (); + Ptr phy = m_phy->GetObject(); - // NS_ASSERT (phy->m_state != EndDeviceLoraPhy::TX && - // phy->m_state != EndDeviceLoraPhy::SLEEP); + // NS_ASSERT (phy->m_state != EndDeviceLoraPhy::TX && + // phy->m_state != EndDeviceLoraPhy::SLEEP); - // Check the Phy layer's state: - // - RX -> We have received a preamble. - // - STANDBY -> Nothing was detected. - switch (phy->GetState ()) + // Check the Phy layer's state: + // - RX -> We have received a preamble. + // - STANDBY -> Nothing was detected. + switch (phy->GetState()) { case EndDeviceLoraPhy::TX: - break; + break; case EndDeviceLoraPhy::SLEEP: - break; + break; case EndDeviceLoraPhy::RX: - // PHY is receiving: let it finish - NS_LOG_DEBUG ("PHY is receiving: Receive will handle the result."); - return; + // PHY is receiving: let it finish + NS_LOG_DEBUG("PHY is receiving: Receive will handle the result."); + return; case EndDeviceLoraPhy::STANDBY: - // Turn PHY layer to sleep - phy->SwitchToSleep (); - break; + // Turn PHY layer to sleep + phy->SwitchToSleep(); + break; } - if (m_retxParams.waitingAck) + if (m_retxParams.waitingAck) { - NS_LOG_DEBUG ("No reception initiated by PHY: rescheduling transmission."); - if (m_retxParams.retxLeft > 0 ) + NS_LOG_DEBUG("No reception initiated by PHY: rescheduling transmission."); + if (m_retxParams.retxLeft > 0) { - NS_LOG_INFO ("We have " << unsigned(m_retxParams.retxLeft) << " retransmissions left: rescheduling transmission."); - this->Send (m_retxParams.packet); + NS_LOG_INFO("We have " << unsigned(m_retxParams.retxLeft) + << " retransmissions left: rescheduling transmission."); + this->Send(m_retxParams.packet); } - else if (m_retxParams.retxLeft == 0 && m_phy->GetObject ()->GetState () != EndDeviceLoraPhy::RX) + else if (m_retxParams.retxLeft == 0 && + m_phy->GetObject()->GetState() != EndDeviceLoraPhy::RX) { - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, false, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG ("Failure: no more retransmissions left. Used " << unsigned(txs) << " transmissions."); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_DEBUG("Failure: no more retransmissions left. Used " << unsigned(txs) + << " transmissions."); - // Reset retransmission parameters - resetRetransmissionParameters (); + // Reset retransmission parameters + resetRetransmissionParameters(); } - else + else { - NS_ABORT_MSG ("The number of retransmissions left is negative ! "); + NS_ABORT_MSG("The number of retransmissions left is negative ! "); } } - else + else { - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft ); - m_requiredTxCallback (txs, true, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_INFO ("We have " << unsigned(m_retxParams.retxLeft) << - " transmissions left. We were not transmitting confirmed messages."); - - // Reset retransmission parameters - resetRetransmissionParameters (); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, true, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_INFO( + "We have " << unsigned(m_retxParams.retxLeft) + << " transmissions left. We were not transmitting confirmed messages."); + + // Reset retransmission parameters + resetRetransmissionParameters(); } } @@ -446,73 +460,77 @@ ClassAEndDeviceLorawanMac::CloseSecondReceiveWindow (void) ///////////////////////// Time -ClassAEndDeviceLorawanMac::GetNextClassTransmissionDelay (Time waitingTime) +ClassAEndDeviceLorawanMac::GetNextClassTransmissionDelay(Time waitingTime) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // This is a new packet from APP; it can not be sent until the end of the - // second receive window (if the second recieve window has not closed yet) - if (!m_retxParams.waitingAck) + // This is a new packet from APP; it can not be sent until the end of the + // second receive window (if the second recieve window has not closed yet) + if (!m_retxParams.waitingAck) { - if (!m_closeFirstWindow.IsExpired () || - !m_closeSecondWindow.IsExpired () || - !m_secondReceiveWindow.IsExpired () ) + if (!m_closeFirstWindow.IsExpired() || !m_closeSecondWindow.IsExpired() || + !m_secondReceiveWindow.IsExpired()) { - NS_LOG_WARN ("Attempting to send when there are receive windows:" << - " Transmission postponed."); - // Compute the duration of a single symbol for the second receive window DR - double tSym = pow (2, GetSfFromDataRate (GetSecondReceiveWindowDataRate ())) / GetBandwidthFromDataRate (GetSecondReceiveWindowDataRate ()); - // Compute the closing time of the second receive window - Time endSecondRxWindow = Time(m_secondReceiveWindow.GetTs()) + Seconds (m_receiveWindowDurationInSymbols*tSym); - - NS_LOG_DEBUG("Duration until endSecondRxWindow for new transmission:" << (endSecondRxWindow - Simulator::Now()).GetSeconds()); - waitingTime = std::max (waitingTime, endSecondRxWindow - Simulator::Now()); + NS_LOG_WARN("Attempting to send when there are receive windows:" + << " Transmission postponed."); + // Compute the duration of a single symbol for the second receive window DR + double tSym = pow(2, GetSfFromDataRate(GetSecondReceiveWindowDataRate())) / + GetBandwidthFromDataRate(GetSecondReceiveWindowDataRate()); + // Compute the closing time of the second receive window + Time endSecondRxWindow = Time(m_secondReceiveWindow.GetTs()) + + Seconds(m_receiveWindowDurationInSymbols * tSym); + + NS_LOG_DEBUG("Duration until endSecondRxWindow for new transmission:" + << (endSecondRxWindow - Simulator::Now()).GetSeconds()); + waitingTime = std::max(waitingTime, endSecondRxWindow - Simulator::Now()); } } - // This is a retransmitted packet, it can not be sent until the end of - // ACK_TIMEOUT (this timer starts when the second receive window was open) - else + // This is a retransmitted packet, it can not be sent until the end of + // ACK_TIMEOUT (this timer starts when the second receive window was open) + else { - double ack_timeout = m_uniformRV->GetValue (1,3); - // Compute the duration until ACK_TIMEOUT (It may be a negative number, but it doesn't matter.) - Time retransmitWaitingTime = Time(m_secondReceiveWindow.GetTs()) - Simulator::Now() + Seconds (ack_timeout); - - NS_LOG_DEBUG("ack_timeout:" << ack_timeout << - " retransmitWaitingTime:" << retransmitWaitingTime.GetSeconds()); - waitingTime = std::max (waitingTime, retransmitWaitingTime); + double ack_timeout = m_uniformRV->GetValue(1, 3); + // Compute the duration until ACK_TIMEOUT (It may be a negative number, but it doesn't + // matter.) + Time retransmitWaitingTime = + Time(m_secondReceiveWindow.GetTs()) - Simulator::Now() + Seconds(ack_timeout); + + NS_LOG_DEBUG("ack_timeout:" << ack_timeout << " retransmitWaitingTime:" + << retransmitWaitingTime.GetSeconds()); + waitingTime = std::max(waitingTime, retransmitWaitingTime); } - return waitingTime; + return waitingTime; } uint8_t -ClassAEndDeviceLorawanMac::GetFirstReceiveWindowDataRate (void) +ClassAEndDeviceLorawanMac::GetFirstReceiveWindowDataRate(void) { - return m_replyDataRateMatrix.at (m_dataRate).at (m_rx1DrOffset); + return m_replyDataRateMatrix.at(m_dataRate).at(m_rx1DrOffset); } void -ClassAEndDeviceLorawanMac::SetSecondReceiveWindowDataRate (uint8_t dataRate) +ClassAEndDeviceLorawanMac::SetSecondReceiveWindowDataRate(uint8_t dataRate) { - m_secondReceiveWindowDataRate = dataRate; + m_secondReceiveWindowDataRate = dataRate; } uint8_t -ClassAEndDeviceLorawanMac::GetSecondReceiveWindowDataRate (void) +ClassAEndDeviceLorawanMac::GetSecondReceiveWindowDataRate(void) { - return m_secondReceiveWindowDataRate; + return m_secondReceiveWindowDataRate; } void -ClassAEndDeviceLorawanMac::SetSecondReceiveWindowFrequency (double frequencyMHz) +ClassAEndDeviceLorawanMac::SetSecondReceiveWindowFrequency(double frequencyMHz) { - m_secondReceiveWindowFrequency = frequencyMHz; + m_secondReceiveWindowFrequency = frequencyMHz; } double -ClassAEndDeviceLorawanMac::GetSecondReceiveWindowFrequency (void) +ClassAEndDeviceLorawanMac::GetSecondReceiveWindowFrequency(void) { - return m_secondReceiveWindowFrequency; + return m_secondReceiveWindowFrequency; } ///////////////////////// @@ -520,43 +538,39 @@ ClassAEndDeviceLorawanMac::GetSecondReceiveWindowFrequency (void) ///////////////////////// void -ClassAEndDeviceLorawanMac::OnRxClassParamSetupReq (Ptr rxParamSetupReq) +ClassAEndDeviceLorawanMac::OnRxClassParamSetupReq(Ptr rxParamSetupReq) { - NS_LOG_FUNCTION (this << rxParamSetupReq); + NS_LOG_FUNCTION(this << rxParamSetupReq); - bool offsetOk = true; - bool dataRateOk = true; + bool offsetOk = true; + bool dataRateOk = true; - uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset (); - uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate (); - double frequency = rxParamSetupReq->GetFrequency (); + uint8_t rx1DrOffset = rxParamSetupReq->GetRx1DrOffset(); + uint8_t rx2DataRate = rxParamSetupReq->GetRx2DataRate(); + double frequency = rxParamSetupReq->GetFrequency(); - NS_LOG_FUNCTION (this << unsigned (rx1DrOffset) << unsigned (rx2DataRate) << - frequency); + NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency); - // Check that the desired offset is valid - if ( !(0 <= rx1DrOffset && rx1DrOffset <= 5)) + // Check that the desired offset is valid + if (!(0 <= rx1DrOffset && rx1DrOffset <= 5)) { - offsetOk = false; + offsetOk = false; } - // Check that the desired data rate is valid - if (GetSfFromDataRate (rx2DataRate) == 0 - || GetBandwidthFromDataRate (rx2DataRate) == 0) + // Check that the desired data rate is valid + if (GetSfFromDataRate(rx2DataRate) == 0 || GetBandwidthFromDataRate(rx2DataRate) == 0) { - dataRateOk = false; + dataRateOk = false; } - // For now, don't check for validity of frequency - m_secondReceiveWindowDataRate = rx2DataRate; - m_rx1DrOffset = rx1DrOffset; - m_secondReceiveWindowFrequency = frequency; - - // Craft a RxParamSetupAns as response - NS_LOG_INFO ("Adding RxParamSetupAns reply"); - m_macCommandList.push_back (CreateObject (offsetOk, - dataRateOk, true)); + // For now, don't check for validity of frequency + m_secondReceiveWindowDataRate = rx2DataRate; + m_rx1DrOffset = rx1DrOffset; + m_secondReceiveWindowFrequency = frequency; + // Craft a RxParamSetupAns as response + NS_LOG_INFO("Adding RxParamSetupAns reply"); + m_macCommandList.push_back(CreateObject(offsetOk, dataRateOk, true)); } } /* namespace lorawan */ diff --git a/model/class-a-end-device-lorawan-mac.h b/model/class-a-end-device-lorawan-mac.h index 2facb632ae..2baa26a3a5 100644 --- a/model/class-a-end-device-lorawan-mac.h +++ b/model/class-a-end-device-lorawan-mac.h @@ -24,194 +24,196 @@ #ifndef CLASS_A_END_DEVICE_LORAWAN_MAC_H #define CLASS_A_END_DEVICE_LORAWAN_MAC_H -#include "ns3/lorawan-mac.h" // Packet -#include "ns3/end-device-lorawan-mac.h" // EndDeviceLorawanMac -#include "ns3/lora-frame-header.h" // RxParamSetupReq +#include "end-device-lorawan-mac.h" // EndDeviceLorawanMac +#include "lora-frame-header.h" // RxParamSetupReq +#include "lorawan-mac.h" // Packet // #include "ns3/random-variable-stream.h" -#include "ns3/lora-device-address.h" +#include "lora-device-address.h" + // #include "ns3/traced-value.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Class representing the MAC layer of a Class A LoRaWAN device. */ class ClassAEndDeviceLorawanMac : public EndDeviceLorawanMac { -public: - static TypeId GetTypeId (void); - - ClassAEndDeviceLorawanMac (); - virtual ~ClassAEndDeviceLorawanMac (); - - ///////////////////// - // Sending methods // - ///////////////////// - - /** - * Add headers and send a packet with the sending function of the physical layer. - * - * \param packet the packet to send - */ - virtual void SendToPhy (Ptr packet); - - ////////////////////////// - // Receiving methods // - ////////////////////////// - - /** - * Receive a packet. - * - * This method is typically registered as a callback in the underlying PHY - * layer so that it's called when a packet is going up the stack. - * - * \param packet the received packet. - */ - virtual void Receive (Ptr packet); - - virtual void FailedReception (Ptr packet); - - /** - * Perform the actions that are required after a packet send. - * - * This function handles opening of the first receive window. - */ - virtual void TxFinished (Ptr packet); - - /** - * Perform operations needed to open the first receive window. - */ - void OpenFirstReceiveWindow (void); - - /** - * Perform operations needed to open the second receive window. - */ - void OpenSecondReceiveWindow (void); - - /** - * Perform operations needed to close the first receive window. - */ - void CloseFirstReceiveWindow (void); - - /** - * Perform operations needed to close the second receive window. - */ - void CloseSecondReceiveWindow (void); - - ///////////////////////// - // Getters and Setters // - ///////////////////////// - - /** - * Find the minimum waiting time before the next possible transmission based - * on End Device's Class Type. - * - * \param waitingTime The minimum waiting time that has to be respected, - * irrespective of the class (e.g., because of duty cycle limitations). - */ - virtual Time GetNextClassTransmissionDelay (Time waitingTime); - - /** - * Get the Data Rate that will be used in the first receive window. - * - * \return The Data Rate - */ - uint8_t GetFirstReceiveWindowDataRate (void); - - /** - * Set the Data Rate to be used in the second receive window. - * - * \param dataRate The Data Rate. - */ - void SetSecondReceiveWindowDataRate (uint8_t dataRate); - - /** - * Get the Data Rate that will be used in the second receive window. - * - * \return The Data Rate - */ - uint8_t GetSecondReceiveWindowDataRate (void); - - /** - * Set the frequency that will be used for the second receive window. - * - * \param frequencyMHz the Frequency. - */ - void SetSecondReceiveWindowFrequency (double frequencyMHz); - - /** - * Get the frequency that is used for the second receive window. - * - * @return The frequency, in MHz - */ - double GetSecondReceiveWindowFrequency (void); - - ///////////////////////// - // MAC command methods // - ///////////////////////// - - /** - * Perform the actions that need to be taken when receiving a RxParamSetupReq - * command based on the Device's Class Type. - * - * \param rxParamSetupReq The Parameter Setup Request, which contains: - * - The offset to set. - * - The data rate to use for the second receive window. - * - The frequency to use for the second receive window. - */ - virtual void OnRxClassParamSetupReq (Ptr rxParamSetupReq); - -private: - - /** - * The interval between when a packet is done sending and when the first - * receive window is opened. - */ - Time m_receiveDelay1; - - /** - * The interval between when a packet is done sending and when the second - * receive window is opened. - */ - Time m_receiveDelay2; - - /** - * The event of the closing the first receive window. - * - * This Event will be canceled if there's a successful reception of a packet. - */ - EventId m_closeFirstWindow; - - /** - * The event of the closing the second receive window. - * - * This Event will be canceled if there's a successful reception of a packet. - */ - EventId m_closeSecondWindow; - - /** - * The event of the second receive window opening. - * - * This Event is used to cancel the second window in case the first one is - * successful. - */ - EventId m_secondReceiveWindow; - - /** - * The frequency to listen on for the second receive window. - */ - double m_secondReceiveWindowFrequency; - - /** - * The Data Rate to listen for during the second downlink transmission. - */ - uint8_t m_secondReceiveWindowDataRate; - - /** - * The RX1DROffset parameter value - */ - uint8_t m_rx1DrOffset; + public: + static TypeId GetTypeId(void); + + ClassAEndDeviceLorawanMac(); + virtual ~ClassAEndDeviceLorawanMac(); + + ///////////////////// + // Sending methods // + ///////////////////// + + /** + * Add headers and send a packet with the sending function of the physical layer. + * + * \param packet the packet to send + */ + virtual void SendToPhy(Ptr packet); + + ////////////////////////// + // Receiving methods // + ////////////////////////// + + /** + * Receive a packet. + * + * This method is typically registered as a callback in the underlying PHY + * layer so that it's called when a packet is going up the stack. + * + * \param packet the received packet. + */ + virtual void Receive(Ptr packet); + + virtual void FailedReception(Ptr packet); + + /** + * Perform the actions that are required after a packet send. + * + * This function handles opening of the first receive window. + */ + virtual void TxFinished(Ptr packet); + + /** + * Perform operations needed to open the first receive window. + */ + void OpenFirstReceiveWindow(void); + + /** + * Perform operations needed to open the second receive window. + */ + void OpenSecondReceiveWindow(void); + + /** + * Perform operations needed to close the first receive window. + */ + void CloseFirstReceiveWindow(void); + + /** + * Perform operations needed to close the second receive window. + */ + void CloseSecondReceiveWindow(void); + + ///////////////////////// + // Getters and Setters // + ///////////////////////// + + /** + * Find the minimum waiting time before the next possible transmission based + * on End Device's Class Type. + * + * \param waitingTime The minimum waiting time that has to be respected, + * irrespective of the class (e.g., because of duty cycle limitations). + */ + virtual Time GetNextClassTransmissionDelay(Time waitingTime); + + /** + * Get the Data Rate that will be used in the first receive window. + * + * \return The Data Rate + */ + uint8_t GetFirstReceiveWindowDataRate(void); + + /** + * Set the Data Rate to be used in the second receive window. + * + * \param dataRate The Data Rate. + */ + void SetSecondReceiveWindowDataRate(uint8_t dataRate); + + /** + * Get the Data Rate that will be used in the second receive window. + * + * \return The Data Rate + */ + uint8_t GetSecondReceiveWindowDataRate(void); + + /** + * Set the frequency that will be used for the second receive window. + * + * \param frequencyMHz the Frequency. + */ + void SetSecondReceiveWindowFrequency(double frequencyMHz); + + /** + * Get the frequency that is used for the second receive window. + * + * @return The frequency, in MHz + */ + double GetSecondReceiveWindowFrequency(void); + + ///////////////////////// + // MAC command methods // + ///////////////////////// + + /** + * Perform the actions that need to be taken when receiving a RxParamSetupReq + * command based on the Device's Class Type. + * + * \param rxParamSetupReq The Parameter Setup Request, which contains: + * - The offset to set. + * - The data rate to use for the second receive window. + * - The frequency to use for the second receive window. + */ + virtual void OnRxClassParamSetupReq(Ptr rxParamSetupReq); + + private: + /** + * The interval between when a packet is done sending and when the first + * receive window is opened. + */ + Time m_receiveDelay1; + + /** + * The interval between when a packet is done sending and when the second + * receive window is opened. + */ + Time m_receiveDelay2; + + /** + * The event of the closing the first receive window. + * + * This Event will be canceled if there's a successful reception of a packet. + */ + EventId m_closeFirstWindow; + + /** + * The event of the closing the second receive window. + * + * This Event will be canceled if there's a successful reception of a packet. + */ + EventId m_closeSecondWindow; + + /** + * The event of the second receive window opening. + * + * This Event is used to cancel the second window in case the first one is + * successful. + */ + EventId m_secondReceiveWindow; + + /** + * The frequency to listen on for the second receive window. + */ + double m_secondReceiveWindowFrequency; + + /** + * The Data Rate to listen for during the second downlink transmission. + */ + uint8_t m_secondReceiveWindowDataRate; + + /** + * The RX1DROffset parameter value + */ + uint8_t m_rx1DrOffset; }; /* ClassAEndDeviceLorawanMac */ } /* namespace lorawan */ diff --git a/model/correlated-shadowing-propagation-loss-model.cc b/model/correlated-shadowing-propagation-loss-model.cc index ff82acd664..63db833697 100644 --- a/model/correlated-shadowing-propagation-loss-model.cc +++ b/model/correlated-shadowing-propagation-loss-model.cc @@ -16,109 +16,114 @@ * Author: Davide Magrin */ -#include "ns3/correlated-shadowing-propagation-loss-model.h" +#include "correlated-shadowing-propagation-loss-model.h" + #include "ns3/double.h" #include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("CorrelatedShadowingPropagationLossModel"); +NS_LOG_COMPONENT_DEFINE("CorrelatedShadowingPropagationLossModel"); -NS_OBJECT_ENSURE_REGISTERED (CorrelatedShadowingPropagationLossModel); +NS_OBJECT_ENSURE_REGISTERED(CorrelatedShadowingPropagationLossModel); TypeId -CorrelatedShadowingPropagationLossModel::GetTypeId (void) +CorrelatedShadowingPropagationLossModel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::CorrelatedShwodingPropagationLossModel") - .SetParent () - .SetGroupName ("Lora") - .AddConstructor () - .AddAttribute ("CorrelationDistance", - "The distance at which the computed shadowing becomes" - "uncorrelated", - DoubleValue (110.0), - MakeDoubleAccessor - (&CorrelatedShadowingPropagationLossModel::m_correlationDistance), - MakeDoubleChecker ()); - return tid; + static TypeId tid = + TypeId("ns3::CorrelatedShwodingPropagationLossModel") + .SetParent() + .SetGroupName("Lora") + .AddConstructor() + .AddAttribute( + "CorrelationDistance", + "The distance at which the computed shadowing becomes" + "uncorrelated", + DoubleValue(110.0), + MakeDoubleAccessor(&CorrelatedShadowingPropagationLossModel::m_correlationDistance), + MakeDoubleChecker()); + return tid; } -CorrelatedShadowingPropagationLossModel::CorrelatedShadowingPropagationLossModel () +CorrelatedShadowingPropagationLossModel::CorrelatedShadowingPropagationLossModel() { } double -CorrelatedShadowingPropagationLossModel::DoCalcRxPower (double txPowerDbm, - Ptr a, - Ptr b) const +CorrelatedShadowingPropagationLossModel::DoCalcRxPower(double txPowerDbm, + Ptr a, + Ptr b) const { - NS_LOG_FUNCTION (this << txPowerDbm << a << b); + NS_LOG_FUNCTION(this << txPowerDbm << a << b); - /* - * Check whether the a MobilityModel is in a grid square that already has - * its shadowing map. - */ - Vector position = a->GetPosition (); + /* + * Check whether the a MobilityModel is in a grid square that already has + * its shadowing map. + */ + Vector position = a->GetPosition(); - double x = position.x; - double y = position.y; + double x = position.x; + double y = position.y; - // Compute the coordinates of the grid square (i.e., round the raw position) - // (x > 0) - (x < 0) is the sign function - int xcoord = - ((x > 0) - (x < 0)) * ((std::fabs (x) + m_correlationDistance / 2) / m_correlationDistance); - int ycoord = - ((y > 0) - (y < 0)) * ((std::fabs (y) + m_correlationDistance / 2) / m_correlationDistance); + // Compute the coordinates of the grid square (i.e., round the raw position) + // (x > 0) - (x < 0) is the sign function + int xcoord = + ((x > 0) - (x < 0)) * ((std::fabs(x) + m_correlationDistance / 2) / m_correlationDistance); + int ycoord = + ((y > 0) - (y < 0)) * ((std::fabs(y) + m_correlationDistance / 2) / m_correlationDistance); - // Wrap coordinates up in a pair - std::pair coordinates (xcoord, ycoord); + // Wrap coordinates up in a pair + std::pair coordinates(xcoord, ycoord); - NS_LOG_DEBUG ("x " << x << ", y " << y); - NS_LOG_DEBUG ("xcoord " << xcoord << ", ycoord " << ycoord); + NS_LOG_DEBUG("x " << x << ", y " << y); + NS_LOG_DEBUG("xcoord " << xcoord << ", ycoord " << ycoord); - // Look for the computed coordinates in the shadowingGrid - std::map, Ptr >::const_iterator it; + // Look for the computed coordinates in the shadowingGrid + std::map, Ptr>::const_iterator it; - it = m_shadowingGrid.find (coordinates); + it = m_shadowingGrid.find(coordinates); - if (it == m_shadowingGrid.end ()) // Did not find the coordinates + if (it == m_shadowingGrid.end()) // Did not find the coordinates { - // If this shadowing grid was not found, create it - NS_LOG_DEBUG ("Creating a new shadowing map to be used at coordinates " - << coordinates.first << " " << coordinates.second); + // If this shadowing grid was not found, create it + NS_LOG_DEBUG("Creating a new shadowing map to be used at coordinates " + << coordinates.first << " " << coordinates.second); - Ptr shadowingMap = - Create (); + Ptr shadowingMap = + Create(); - m_shadowingGrid[coordinates] = shadowingMap; + m_shadowingGrid[coordinates] = shadowingMap; } - else + else { - NS_LOG_DEBUG ("This square already has its shadowingMap!"); + NS_LOG_DEBUG("This square already has its shadowingMap!"); } - // Place the iterator on the coordinates - it = m_shadowingGrid.find (coordinates); + // Place the iterator on the coordinates + it = m_shadowingGrid.find(coordinates); - // Get b's position in a's ShadowingMap - CorrelatedShadowingPropagationLossModel::Position bPosition - (b->GetPosition ().x, b->GetPosition ().y); + // Get b's position in a's ShadowingMap + CorrelatedShadowingPropagationLossModel::Position bPosition(b->GetPosition().x, + b->GetPosition().y); - // Use the map of the a MobilityModel to determine the value of shadowing - // that corresponds to the position of the MobilityModel b. - double loss = it->second->GetLoss (bPosition); + // Use the map of the a MobilityModel to determine the value of shadowing + // that corresponds to the position of the MobilityModel b. + double loss = it->second->GetLoss(bPosition); - NS_LOG_INFO ("Shadowing loss: " << loss); + NS_LOG_INFO("Shadowing loss: " << loss); - return txPowerDbm - loss; + return txPowerDbm - loss; } int64_t -CorrelatedShadowingPropagationLossModel::DoAssignStreams (int64_t stream) +CorrelatedShadowingPropagationLossModel::DoAssignStreams(int64_t stream) { - return 0; + return 0; } /********************************* @@ -126,176 +131,172 @@ CorrelatedShadowingPropagationLossModel::DoAssignStreams (int64_t stream) *********************************/ // k^{-1} was computed offline -const double CorrelatedShadowingPropagationLossModel::ShadowingMap::m_kInv[4][4] = -{ - {1.27968707244633, -0.366414485833771, -0.0415206295795327, -0.366414485833771}, - {-0.366414485833771, 1.27968707244633, -0.366414485833771, -0.0415206295795327}, - {-0.0415206295795327, -0.366414485833771, 1.27968707244633, -0.366414485833771}, - {-0.366414485833771, -0.0415206295795327, -0.366414485833771, 1.27968707244633} -}; - -CorrelatedShadowingPropagationLossModel::ShadowingMap::ShadowingMap () : - m_correlationDistance (110) +const double CorrelatedShadowingPropagationLossModel::ShadowingMap::m_kInv[4][4] = { + {1.27968707244633, -0.366414485833771, -0.0415206295795327, -0.366414485833771}, + {-0.366414485833771, 1.27968707244633, -0.366414485833771, -0.0415206295795327}, + {-0.0415206295795327, -0.366414485833771, 1.27968707244633, -0.366414485833771}, + {-0.366414485833771, -0.0415206295795327, -0.366414485833771, 1.27968707244633}}; + +CorrelatedShadowingPropagationLossModel::ShadowingMap::ShadowingMap() + : m_correlationDistance(110) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // The generation of new variables and positions along the grid is handled - // by the GetLoss function. Here, we only create the normal random variable. - m_shadowingValue = CreateObject (); - m_shadowingValue->SetAttribute ("Mean", DoubleValue (0.0)); - m_shadowingValue->SetAttribute ("Variance", DoubleValue (16.0)); + // The generation of new variables and positions along the grid is handled + // by the GetLoss function. Here, we only create the normal random variable. + m_shadowingValue = CreateObject(); + m_shadowingValue->SetAttribute("Mean", DoubleValue(0.0)); + m_shadowingValue->SetAttribute("Variance", DoubleValue(16.0)); } -CorrelatedShadowingPropagationLossModel::ShadowingMap::~ShadowingMap () +CorrelatedShadowingPropagationLossModel::ShadowingMap::~ShadowingMap() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } double -CorrelatedShadowingPropagationLossModel::ShadowingMap::GetLoss - (CorrelatedShadowingPropagationLossModel::Position position) +CorrelatedShadowingPropagationLossModel::ShadowingMap::GetLoss( + CorrelatedShadowingPropagationLossModel::Position position) { - NS_LOG_FUNCTION (this << position.x << position.y); - - // Verify whether this position is already in the shadowingMap. Since the - // Position implementation overloads the == operator, this comparison - // between doubles is ok and we can use std::map's find function. - std::map::const_iterator it; - it = m_shadowingMap.find (position); - - // If it's not found (i.e, if find returns the end of the map), we need to - // generate the value at the specified position. - if (it == m_shadowingMap.end ()) + NS_LOG_FUNCTION(this << position.x << position.y); + + // Verify whether this position is already in the shadowingMap. Since the + // Position implementation overloads the == operator, this comparison + // between doubles is ok and we can use std::map's find function. + std::map::const_iterator it; + it = m_shadowingMap.find(position); + + // If it's not found (i.e, if find returns the end of the map), we need to + // generate the value at the specified position. + if (it == m_shadowingMap.end()) { - // Get the coordinates of the position - double x = position.x; - double y = position.y; - int xcoord = - ((x > 0) - (x < 0)) * ((std::fabs (x) + m_correlationDistance / 2) / m_correlationDistance); - int ycoord = - ((y > 0) - (y < 0)) * ((std::fabs (y) + m_correlationDistance / 2) / m_correlationDistance); - - // Verify whether there already are the 4 surrounding positions in the - // map - double xmin = xcoord * m_correlationDistance - m_correlationDistance / 2; - double xmax = xcoord * m_correlationDistance + m_correlationDistance / 2; - double ymin = ycoord * m_correlationDistance - m_correlationDistance / 2; - double ymax = ycoord * m_correlationDistance + m_correlationDistance / 2; - - CorrelatedShadowingPropagationLossModel::Position lowerLeft (xmin, ymin); - CorrelatedShadowingPropagationLossModel::Position upperLeft (xmin, ymax); - CorrelatedShadowingPropagationLossModel::Position lowerRight (xmax, ymin); - CorrelatedShadowingPropagationLossModel::Position upperRight (xmax, ymax); - - NS_LOG_DEBUG ("Generating a new shadowing value in the following quadrant:"); - NS_LOG_DEBUG ("xmin " << xmin << ", xmax " << xmax << - ", ymin " << ymin << ", ymax " << ymax); - - // Use the map's insert method to insert the coordinates of the 4 - // surrounding positions (if they are already there, they won't be - // substituted thanks to the map's implementation). - // TODO: Avoid useless generation of ShadowingMap values. This can be - // done by performing some checks (and not leveraging the map - // implementation) - double q11 = m_shadowingValue->GetValue (); - NS_LOG_DEBUG ("Lower left corner: " << q11); - m_shadowingMap[lowerLeft] = q11; - double q12 = m_shadowingValue->GetValue (); - NS_LOG_DEBUG ("Upper left corner: " << q12); - m_shadowingMap[upperLeft] = q12; - double q21 = m_shadowingValue->GetValue (); - NS_LOG_DEBUG ("Lower right corner: " << q21); - m_shadowingMap[lowerRight] = q21; - double q22 = m_shadowingValue->GetValue (); - NS_LOG_DEBUG ("Upper right corner: " << q22); - m_shadowingMap[upperRight] = q22; - - NS_LOG_DEBUG (q11 << " " << q12 << " " << q21 << " " << q22 << " "); - - // The c matrix contains the positions of the 4 vertices - double c[2][4] = {{xmin, xmax, xmax, xmin}, {ymin, ymin, ymax, ymax}}; - - // For the following procedure, reference: - // S. Schlegel et al., "On the Interpolation of Data with Normally - // Distributed Uncertainty for Visualization", IEEE Transactions on - // Visualization and Computer Graphics, vol. 18, no. 12, Dec. 2012. - - // Compute the phi coefficients - double phi1 = 0; - double phi2 = 0; - double phi3 = 0; - double phi4 = 0; - - for (int j = 0; j < 4; j++) + // Get the coordinates of the position + double x = position.x; + double y = position.y; + int xcoord = ((x > 0) - (x < 0)) * + ((std::fabs(x) + m_correlationDistance / 2) / m_correlationDistance); + int ycoord = ((y > 0) - (y < 0)) * + ((std::fabs(y) + m_correlationDistance / 2) / m_correlationDistance); + + // Verify whether there already are the 4 surrounding positions in the + // map + double xmin = xcoord * m_correlationDistance - m_correlationDistance / 2; + double xmax = xcoord * m_correlationDistance + m_correlationDistance / 2; + double ymin = ycoord * m_correlationDistance - m_correlationDistance / 2; + double ymax = ycoord * m_correlationDistance + m_correlationDistance / 2; + + CorrelatedShadowingPropagationLossModel::Position lowerLeft(xmin, ymin); + CorrelatedShadowingPropagationLossModel::Position upperLeft(xmin, ymax); + CorrelatedShadowingPropagationLossModel::Position lowerRight(xmax, ymin); + CorrelatedShadowingPropagationLossModel::Position upperRight(xmax, ymax); + + NS_LOG_DEBUG("Generating a new shadowing value in the following quadrant:"); + NS_LOG_DEBUG("xmin " << xmin << ", xmax " << xmax << ", ymin " << ymin << ", ymax " + << ymax); + + // Use the map's insert method to insert the coordinates of the 4 + // surrounding positions (if they are already there, they won't be + // substituted thanks to the map's implementation). + // TODO: Avoid useless generation of ShadowingMap values. This can be + // done by performing some checks (and not leveraging the map + // implementation) + double q11 = m_shadowingValue->GetValue(); + NS_LOG_DEBUG("Lower left corner: " << q11); + m_shadowingMap[lowerLeft] = q11; + double q12 = m_shadowingValue->GetValue(); + NS_LOG_DEBUG("Upper left corner: " << q12); + m_shadowingMap[upperLeft] = q12; + double q21 = m_shadowingValue->GetValue(); + NS_LOG_DEBUG("Lower right corner: " << q21); + m_shadowingMap[lowerRight] = q21; + double q22 = m_shadowingValue->GetValue(); + NS_LOG_DEBUG("Upper right corner: " << q22); + m_shadowingMap[upperRight] = q22; + + NS_LOG_DEBUG(q11 << " " << q12 << " " << q21 << " " << q22 << " "); + + // The c matrix contains the positions of the 4 vertices + double c[2][4] = {{xmin, xmax, xmax, xmin}, {ymin, ymin, ymax, ymax}}; + + // For the following procedure, reference: + // S. Schlegel et al., "On the Interpolation of Data with Normally + // Distributed Uncertainty for Visualization", IEEE Transactions on + // Visualization and Computer Graphics, vol. 18, no. 12, Dec. 2012. + + // Compute the phi coefficients + double phi1 = 0; + double phi2 = 0; + double phi3 = 0; + double phi4 = 0; + + for (int j = 0; j < 4; j++) { - double distance = sqrt ((c[0][j] - x) * (c[0][j] - x) + (c[1][j] - y) * (c[1][j] - y)); + double distance = sqrt((c[0][j] - x) * (c[0][j] - x) + (c[1][j] - y) * (c[1][j] - y)); - NS_LOG_DEBUG ("Distance: " << distance); + NS_LOG_DEBUG("Distance: " << distance); - double k = std::exp (-distance / m_correlationDistance); - phi1 = phi1 + m_kInv[0][j] * k; - phi2 = phi2 + m_kInv[1][j] * k; - phi3 = phi3 + m_kInv[2][j] * k; - phi4 = phi4 + m_kInv[3][j] * k; + double k = std::exp(-distance / m_correlationDistance); + phi1 = phi1 + m_kInv[0][j] * k; + phi2 = phi2 + m_kInv[1][j] * k; + phi3 = phi3 + m_kInv[2][j] * k; + phi4 = phi4 + m_kInv[3][j] * k; } - NS_LOG_DEBUG ("Phi: " << phi1 << " " << phi2 << " " << phi3 << " " << - phi4 << " "); + NS_LOG_DEBUG("Phi: " << phi1 << " " << phi2 << " " << phi3 << " " << phi4 << " "); - double shadowing = q11 * phi1 + q21 * phi2 + q22 * phi3 + q12 * phi4; + double shadowing = q11 * phi1 + q21 * phi2 + q22 * phi3 + q12 * phi4; - // Add the newly computed shadowing value to the shadowing map - m_shadowingMap[position] = shadowing; - NS_LOG_DEBUG ("Created new shadowing map: " << shadowing); + // Add the newly computed shadowing value to the shadowing map + m_shadowingMap[position] = shadowing; + NS_LOG_DEBUG("Created new shadowing map: " << shadowing); } - else + else { - NS_LOG_DEBUG ("Shadowing map for this location already exists"); + NS_LOG_DEBUG("Shadowing map for this location already exists"); } - return m_shadowingMap[position]; + return m_shadowingMap[position]; } /***************************** * Position Implementation * *****************************/ -CorrelatedShadowingPropagationLossModel::Position::Position () +CorrelatedShadowingPropagationLossModel::Position::Position() { } -CorrelatedShadowingPropagationLossModel::Position::Position (double x, - double y) +CorrelatedShadowingPropagationLossModel::Position::Position(double x, double y) { - this->x = x; - this->y = y; + this->x = x; + this->y = y; } /* * Since Position holds two doubles, some tolerance must be taken into * account when comparing for equality. */ -bool CorrelatedShadowingPropagationLossModel::Position::operator== - (const CorrelatedShadowingPropagationLossModel::Position &other) const +bool +CorrelatedShadowingPropagationLossModel::Position::operator==( + const CorrelatedShadowingPropagationLossModel::Position& other) const { - double EPSILON = 0.1; // Arbitrary value for the tolerance, 10 cm. - return ((fabs (this->x - other.x) < EPSILON) - && (fabs (this->y - other.y) < EPSILON)); + double EPSILON = 0.1; // Arbitrary value for the tolerance, 10 cm. + return ((fabs(this->x - other.x) < EPSILON) && (fabs(this->y - other.y) < EPSILON)); } /* * In order to use Positions as keys in a map, we have to be able to order * them correctly. */ -bool CorrelatedShadowingPropagationLossModel::Position::operator< - (const CorrelatedShadowingPropagationLossModel::Position &other) const +bool +CorrelatedShadowingPropagationLossModel::Position::operator<( + const CorrelatedShadowingPropagationLossModel::Position& other) const { - if (this->x != other.x) + if (this->x != other.x) { - return this->x < other.x; + return this->x < other.x; } - return this->y < other.y; -} -} + return this->y < other.y; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/correlated-shadowing-propagation-loss-model.h b/model/correlated-shadowing-propagation-loss-model.h index 6db4a6a377..5578c4c7cb 100644 --- a/model/correlated-shadowing-propagation-loss-model.h +++ b/model/correlated-shadowing-propagation-loss-model.h @@ -19,161 +19,162 @@ #ifndef CORRELATED_SHADOWING_PROPAGATION_LOSS_MODEL_H #define CORRELATED_SHADOWING_PROPAGATION_LOSS_MODEL_H -#include "ns3/propagation-loss-model.h" #include "ns3/mobility-model.h" -#include "ns3/vector.h" +#include "ns3/propagation-loss-model.h" #include "ns3/random-variable-stream.h" +#include "ns3/vector.h" -namespace ns3 { +namespace ns3 +{ class MobilityModel; -namespace lorawan { + +namespace lorawan +{ class CorrelatedShadowingPropagationLossModel : public PropagationLossModel { + public: + class Position + { + public: + Position(); + Position(double x, double y); + double x; + double y; + + bool operator==(const Position& other) const; + bool operator<(const Position& other) const; + }; + + class ShadowingMap + : public SimpleRefCount + { + public: + /** + * Constructor. + * This initializes the shadowing map with a grid of independent + * shadowing values, one m_correlationDistance meters apart from the next + * one. The result is something like: + * o---o---o---o---o + * | | | | | + * o---o---o---o---o + * | | | | | + * o---o---o---o---o + * | | | | | + * o---o---o---o---o + * where at each o we have an independently generated shadowing value. + * We can then interpolate the 4 values surrounding any point in space + * in order to get a correlated shadowing value. After generating this + * value, we will add it to the map so that we don't have to compute it + * twice. Also, since interpolation is a deterministic operation, we are + * guaranteed that, as long as the grid doesn't change, also two values + * generated in the same square will be correlated. + */ + ShadowingMap(); + + ~ShadowingMap(); + + /** + * Get the loss for a certain position. + * If this position is not already in the map, add it by computing the + * interpolation of neighboring shadowing values belonging to the grid. + */ + double GetLoss(CorrelatedShadowingPropagationLossModel::Position position); + + private: + /** + * For each Position, this map gives a corresponding loss. + * The map contains a basic grid that is initialized at construction + * time, and then newly computed values are added as they are created. + */ + std::map m_shadowingMap; + + /** + * The distance after which two samples are to be considered almost + * uncorrelated + */ + double m_correlationDistance; + + /** + * The normal random variable that is used to obtain shadowing values. + */ + Ptr m_shadowingValue; + + /** + * The inverted K matrix. + * This matrix is used to compute the coefficients to be used when + * interpolating the vertices of a grid square. + */ + static const double m_kInv[4][4]; + }; + + static TypeId GetTypeId(void); -public: - class Position - { -public: - Position (); - Position (double x, double y); - double x; - double y; - - bool operator== (const Position &other) const; - bool operator< (const Position &other) const; - }; - - class ShadowingMap : public - SimpleRefCount - { -public: /** * Constructor. - * This initializes the shadowing map with a grid of independent - * shadowing values, one m_correlationDistance meters apart from the next - * one. The result is something like: - * o---o---o---o---o - * | | | | | - * o---o---o---o---o - * | | | | | - * o---o---o---o---o - * | | | | | - * o---o---o---o---o - * where at each o we have an independently generated shadowing value. - * We can then interpolate the 4 values surrounding any point in space - * in order to get a correlated shadowing value. After generating this - * value, we will add it to the map so that we don't have to compute it - * twice. Also, since interpolation is a deterministic operation, we are - * guaranteed that, as long as the grid doesn't change, also two values - * generated in the same square will be correlated. */ - ShadowingMap (); - - ~ShadowingMap (); + CorrelatedShadowingPropagationLossModel(); /** - * Get the loss for a certain position. - * If this position is not already in the map, add it by computing the - * interpolation of neighboring shadowing values belonging to the grid. + * Set the correlation distance for newly created ShadowingMap instances */ - double GetLoss (CorrelatedShadowingPropagationLossModel::Position position); + void SetCorrelationDistance(double distance); -private: /** - * For each Position, this map gives a corresponding loss. - * The map contains a basic grid that is initialized at construction - * time, and then newly computed values are added as they are created. + * Get the correlation distance that is currently being used. */ - std::map - m_shadowingMap; + double GetCorrelationDistance(void); - /** - * The distance after which two samples are to be considered almost - * uncorrelated - */ - double m_correlationDistance; + private: + virtual double DoCalcRxPower(double txPowerDbm, + Ptr a, + Ptr b) const; - /** - * The normal random variable that is used to obtain shadowing values. - */ - Ptr m_shadowingValue; + virtual int64_t DoAssignStreams(int64_t stream); + + double m_correlationDistance; //!< The correlation distance for the ShadowingMap /** - * The inverted K matrix. - * This matrix is used to compute the coefficients to be used when - * interpolating the vertices of a grid square. + * Map linking a square to a ShadowingMap. + * Each square of the shadowing grid has a corresponding ShadowingMap, and a + * square is identified by a pair of coordinates. Coordinates are computed as + * such: + * + * o---------o---------o---------o---------o---------o + * | | | ' | | | + * | (-2,2) | (-1,2) | (0,2) | (1,2) | (2,2) | + * | | | ' | | | + * o---------o---------o----+----o---------o---------o + * | | | ' | | | + * | (-2,1) | (-1,1) | (0,1) | (1,1) | (2,1) | + * | | | ' | | | + * o---------o---------o----+----o---------o---------o + * | | | ' | | | + * |--(-2,0)-+--(-1,0)-+--(0,0)--+--(1,0)--+--(2,0)--| + * | | | ' | | | + * o---------o---------o----+----o---------o---------o + * | | | ' | | | + * | (-2,-1) | (-1,-1) | (0,-1) | (1,-1) | (2,-1) | + * | | | ' | | | + * o---------o---------o----+----o---------o---------o + * | | | ' | | | + * | (-2,-2) | (-1,-2) | (0,-2) | (1,-2) | (2,-2) | + * | | | ' | | | + * o---------o---------o---------o---------o---------o + * + * For each one of these coordinates, a ShadowingMap is computed. That is, + * each one of the points belonging to the same square sees the same + * shadowing for the points around it. This is one level of correlation for + * the shadowing, i.e. close nodes transmitting to the same point will see + * the same shadowing since they are using the same shadowing map. + * Further, the ShadowingMap will be "smooth": when transmitting from point + * a to points b and c, the shadowing experienced by b and c will be similar + * if they are close (ideally, within a correlation distance). */ - static const double m_kInv[4][4]; - }; - - static TypeId GetTypeId (void); - - /** - * Constructor. - */ - CorrelatedShadowingPropagationLossModel (); - - /** - * Set the correlation distance for newly created ShadowingMap instances - */ - void SetCorrelationDistance (double distance); - - /** - * Get the correlation distance that is currently being used. - */ - double GetCorrelationDistance (void); - -private: - virtual double DoCalcRxPower (double txPowerDbm, - Ptr a, - Ptr b) const; - - virtual int64_t DoAssignStreams (int64_t stream); - - double m_correlationDistance; //!< The correlation distance for the ShadowingMap - - /** - * Map linking a square to a ShadowingMap. - * Each square of the shadowing grid has a corresponding ShadowingMap, and a - * square is identified by a pair of coordinates. Coordinates are computed as - * such: - * - * o---------o---------o---------o---------o---------o - * | | | ' | | | - * | (-2,2) | (-1,2) | (0,2) | (1,2) | (2,2) | - * | | | ' | | | - * o---------o---------o----+----o---------o---------o - * | | | ' | | | - * | (-2,1) | (-1,1) | (0,1) | (1,1) | (2,1) | - * | | | ' | | | - * o---------o---------o----+----o---------o---------o - * | | | ' | | | - * |--(-2,0)-+--(-1,0)-+--(0,0)--+--(1,0)--+--(2,0)--| - * | | | ' | | | - * o---------o---------o----+----o---------o---------o - * | | | ' | | | - * | (-2,-1) | (-1,-1) | (0,-1) | (1,-1) | (2,-1) | - * | | | ' | | | - * o---------o---------o----+----o---------o---------o - * | | | ' | | | - * | (-2,-2) | (-1,-2) | (0,-2) | (1,-2) | (2,-2) | - * | | | ' | | | - * o---------o---------o---------o---------o---------o - * - * For each one of these coordinates, a ShadowingMap is computed. That is, - * each one of the points belonging to the same square sees the same - * shadowing for the points around it. This is one level of correlation for - * the shadowing, i.e. close nodes transmitting to the same point will see - * the same shadowing since they are using the same shadowing map. - * Further, the ShadowingMap will be "smooth": when transmitting from point - * a to points b and c, the shadowing experienced by b and c will be similar - * if they are close (ideally, within a correlation distance). - */ - mutable std::map, Ptr > m_shadowingGrid; + mutable std::map, Ptr> m_shadowingGrid; }; -} +} // namespace lorawan -} +} // namespace ns3 #endif diff --git a/model/end-device-lora-phy.cc b/model/end-device-lora-phy.cc index 6cd058f771..d4965e20bb 100644 --- a/model/end-device-lora-phy.cc +++ b/model/end-device-lora-phy.cc @@ -18,187 +18,191 @@ * Author: Davide Magrin */ -#include -#include "ns3/end-device-lora-phy.h" -#include "ns3/simulator.h" -#include "ns3/lora-tag.h" +#include "end-device-lora-phy.h" + +#include "lora-tag.h" + #include "ns3/log.h" +#include "ns3/simulator.h" -namespace ns3 { -namespace lorawan { +#include -NS_LOG_COMPONENT_DEFINE ("EndDeviceLoraPhy"); +namespace ns3 +{ +namespace lorawan +{ + +NS_LOG_COMPONENT_DEFINE("EndDeviceLoraPhy"); -NS_OBJECT_ENSURE_REGISTERED (EndDeviceLoraPhy); +NS_OBJECT_ENSURE_REGISTERED(EndDeviceLoraPhy); /************************** * Listener destructor * *************************/ -EndDeviceLoraPhyListener::~EndDeviceLoraPhyListener () +EndDeviceLoraPhyListener::~EndDeviceLoraPhyListener() { } TypeId -EndDeviceLoraPhy::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::EndDeviceLoraPhy") - .SetParent () - .SetGroupName ("lorawan") - .AddTraceSource ("LostPacketBecauseWrongFrequency", - "Trace source indicating a packet " - "could not be correctly decoded because" - "the ED was listening on a different frequency", - MakeTraceSourceAccessor (&EndDeviceLoraPhy::m_wrongFrequency), - "ns3::Packet::TracedCallback") - .AddTraceSource ("LostPacketBecauseWrongSpreadingFactor", - "Trace source indicating a packet " - "could not be correctly decoded because" - "the ED was listening for a different Spreading Factor", - MakeTraceSourceAccessor (&EndDeviceLoraPhy::m_wrongSf), - "ns3::Packet::TracedCallback") - .AddTraceSource ("EndDeviceState", - "The current state of the device", - MakeTraceSourceAccessor - (&EndDeviceLoraPhy::m_state), - "ns3::TracedValueCallback::EndDeviceLoraPhy::State"); - return tid; +EndDeviceLoraPhy::GetTypeId(void) +{ + static TypeId tid = + TypeId("ns3::EndDeviceLoraPhy") + .SetParent() + .SetGroupName("lorawan") + .AddTraceSource("LostPacketBecauseWrongFrequency", + "Trace source indicating a packet " + "could not be correctly decoded because" + "the ED was listening on a different frequency", + MakeTraceSourceAccessor(&EndDeviceLoraPhy::m_wrongFrequency), + "ns3::Packet::TracedCallback") + .AddTraceSource("LostPacketBecauseWrongSpreadingFactor", + "Trace source indicating a packet " + "could not be correctly decoded because" + "the ED was listening for a different Spreading Factor", + MakeTraceSourceAccessor(&EndDeviceLoraPhy::m_wrongSf), + "ns3::Packet::TracedCallback") + .AddTraceSource("EndDeviceState", + "The current state of the device", + MakeTraceSourceAccessor(&EndDeviceLoraPhy::m_state), + "ns3::TracedValueCallback::EndDeviceLoraPhy::State"); + return tid; } // Initialize the device with some common settings. // These will then be changed by helpers. -EndDeviceLoraPhy::EndDeviceLoraPhy () : - m_state (SLEEP), - m_frequency (868.1), - m_sf (7) +EndDeviceLoraPhy::EndDeviceLoraPhy() + : m_state(SLEEP), + m_frequency(868.1), + m_sf(7) { } -EndDeviceLoraPhy::~EndDeviceLoraPhy () +EndDeviceLoraPhy::~EndDeviceLoraPhy() { } // Downlink sensitivity (from SX1272 datasheet) // {SF7, SF8, SF9, SF10, SF11, SF12} // These sensitivites are for a bandwidth of 125000 Hz -const double EndDeviceLoraPhy::sensitivity[6] = -{-124, -127, -130, -133, -135, -137}; +const double EndDeviceLoraPhy::sensitivity[6] = {-124, -127, -130, -133, -135, -137}; void -EndDeviceLoraPhy::SetSpreadingFactor (uint8_t sf) +EndDeviceLoraPhy::SetSpreadingFactor(uint8_t sf) { - m_sf = sf; + m_sf = sf; } uint8_t -EndDeviceLoraPhy::GetSpreadingFactor (void) +EndDeviceLoraPhy::GetSpreadingFactor(void) { - return m_sf; + return m_sf; } bool -EndDeviceLoraPhy::IsTransmitting (void) +EndDeviceLoraPhy::IsTransmitting(void) { - return m_state == TX; + return m_state == TX; } bool -EndDeviceLoraPhy::IsOnFrequency (double frequencyMHz) +EndDeviceLoraPhy::IsOnFrequency(double frequencyMHz) { - return m_frequency == frequencyMHz; + return m_frequency == frequencyMHz; } void -EndDeviceLoraPhy::SetFrequency (double frequencyMHz) +EndDeviceLoraPhy::SetFrequency(double frequencyMHz) { - m_frequency = frequencyMHz; + m_frequency = frequencyMHz; } void -EndDeviceLoraPhy::SwitchToStandby (void) +EndDeviceLoraPhy::SwitchToStandby(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_state = STANDBY; + m_state = STANDBY; - // Notify listeners of the state change - for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) + // Notify listeners of the state change + for (Listeners::const_iterator i = m_listeners.begin(); i != m_listeners.end(); i++) { - (*i)->NotifyStandby (); + (*i)->NotifyStandby(); } } void -EndDeviceLoraPhy::SwitchToRx (void) +EndDeviceLoraPhy::SwitchToRx(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - NS_ASSERT (m_state == STANDBY); + NS_ASSERT(m_state == STANDBY); - m_state = RX; + m_state = RX; - // Notify listeners of the state change - for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) + // Notify listeners of the state change + for (Listeners::const_iterator i = m_listeners.begin(); i != m_listeners.end(); i++) { - (*i)->NotifyRxStart (); + (*i)->NotifyRxStart(); } } void -EndDeviceLoraPhy::SwitchToTx (double txPowerDbm) +EndDeviceLoraPhy::SwitchToTx(double txPowerDbm) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - NS_ASSERT (m_state != RX); + NS_ASSERT(m_state != RX); - m_state = TX; + m_state = TX; - // Notify listeners of the state change - for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) + // Notify listeners of the state change + for (Listeners::const_iterator i = m_listeners.begin(); i != m_listeners.end(); i++) { - (*i)->NotifyTxStart (txPowerDbm); + (*i)->NotifyTxStart(txPowerDbm); } } void -EndDeviceLoraPhy::SwitchToSleep (void) +EndDeviceLoraPhy::SwitchToSleep(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - NS_ASSERT (m_state == STANDBY); + NS_ASSERT(m_state == STANDBY); - m_state = SLEEP; + m_state = SLEEP; - // Notify listeners of the state change - for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) + // Notify listeners of the state change + for (Listeners::const_iterator i = m_listeners.begin(); i != m_listeners.end(); i++) { - (*i)->NotifySleep (); + (*i)->NotifySleep(); } } EndDeviceLoraPhy::State -EndDeviceLoraPhy::GetState (void) +EndDeviceLoraPhy::GetState(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_state; + return m_state; } void -EndDeviceLoraPhy::RegisterListener (EndDeviceLoraPhyListener *listener) +EndDeviceLoraPhy::RegisterListener(EndDeviceLoraPhyListener* listener) { - m_listeners.push_back (listener); + m_listeners.push_back(listener); } void -EndDeviceLoraPhy::UnregisterListener (EndDeviceLoraPhyListener *listener) +EndDeviceLoraPhy::UnregisterListener(EndDeviceLoraPhyListener* listener) { - ListenersI i = find (m_listeners.begin (), m_listeners.end (), listener); - if (i != m_listeners.end ()) + ListenersI i = find(m_listeners.begin(), m_listeners.end(), listener); + if (i != m_listeners.end()) { - m_listeners.erase (i); + m_listeners.erase(i); } } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/end-device-lora-phy.h b/model/end-device-lora-phy.h index f587b14eeb..6b84852790 100644 --- a/model/end-device-lora-phy.h +++ b/model/end-device-lora-phy.h @@ -23,16 +23,19 @@ #ifndef END_DEVICE_LORA_PHY_H #define END_DEVICE_LORA_PHY_H -#include "ns3/object.h" -#include "ns3/traced-value.h" -#include "ns3/net-device.h" -#include "ns3/nstime.h" +#include "lora-phy.h" + #include "ns3/mobility-model.h" +#include "ns3/net-device.h" #include "ns3/node.h" -#include "ns3/lora-phy.h" +#include "ns3/nstime.h" +#include "ns3/object.h" +#include "ns3/traced-value.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; @@ -41,44 +44,44 @@ class LoraChannel; */ class EndDeviceLoraPhyListener { -public: - virtual ~EndDeviceLoraPhyListener (); - - /** - * We have received the first bit of a packet. We decided - * that we could synchronize on this packet. It does not mean - * we will be able to successfully receive completely the - * whole packet. It means that we will report a BUSY status until - * one of the following happens: - * - NotifyRxEndOk - * - NotifyRxEndError - * - NotifyTxStart - * - * \param duration the expected duration of the packet reception. - */ - virtual void NotifyRxStart () = 0; - - /** - * We are about to send the first bit of the packet. - * We do not send any event to notify the end of - * transmission. Listeners should assume that the - * channel implicitely reverts to the idle state - * unless they have received a cca busy report. - * - * \param duration the expected transmission duration. - * \param txPowerDbm the nominal tx power in dBm - */ - virtual void NotifyTxStart (double txPowerDbm) = 0; - - /** - * Notify listeners that we went to sleep - */ - virtual void NotifySleep (void) = 0; - - /** - * Notify listeners that we woke up - */ - virtual void NotifyStandby (void) = 0; + public: + virtual ~EndDeviceLoraPhyListener(); + + /** + * We have received the first bit of a packet. We decided + * that we could synchronize on this packet. It does not mean + * we will be able to successfully receive completely the + * whole packet. It means that we will report a BUSY status until + * one of the following happens: + * - NotifyRxEndOk + * - NotifyRxEndError + * - NotifyTxStart + * + * \param duration the expected duration of the packet reception. + */ + virtual void NotifyRxStart() = 0; + + /** + * We are about to send the first bit of the packet. + * We do not send any event to notify the end of + * transmission. Listeners should assume that the + * channel implicitely reverts to the idle state + * unless they have received a cca busy report. + * + * \param duration the expected transmission duration. + * \param txPowerDbm the nominal tx power in dBm + */ + virtual void NotifyTxStart(double txPowerDbm) = 0; + + /** + * Notify listeners that we went to sleep + */ + virtual void NotifySleep(void) = 0; + + /** + * Notify listeners that we woke up + */ + virtual void NotifyStandby(void) = 0; }; /** @@ -103,175 +106,179 @@ class EndDeviceLoraPhyListener */ class EndDeviceLoraPhy : public LoraPhy { -public: - /** - * An enumeration of the possible states of an EndDeviceLoraPhy. - * It makes sense to define a state for End Devices since there's only one - * demodulator which can either send, receive, stay idle or go in a deep - * sleep state. - */ - enum State - { + public: /** - * The PHY layer is sleeping. - * During sleep, the device is not listening for incoming messages. + * An enumeration of the possible states of an EndDeviceLoraPhy. + * It makes sense to define a state for End Devices since there's only one + * demodulator which can either send, receive, stay idle or go in a deep + * sleep state. */ - SLEEP, + enum State + { + /** + * The PHY layer is sleeping. + * During sleep, the device is not listening for incoming messages. + */ + SLEEP, + + /** + * The PHY layer is in STANDBY. + * When the PHY is in this state, it's listening to the channel, and + * it's also ready to transmit data passed to it by the MAC layer. + */ + STANDBY, + + /** + * The PHY layer is sending a packet. + * During transmission, the device cannot receive any packet or send + * any additional packet. + */ + TX, + + /** + * The PHY layer is receiving a packet. + * While the device is locked on an incoming packet, transmission is + * not possible. + */ + RX + }; + + static TypeId GetTypeId(void); + + // Constructor and destructor + EndDeviceLoraPhy(); + virtual ~EndDeviceLoraPhy(); + + // Implementation of LoraPhy's pure virtual functions + virtual void StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz) = 0; + + // Implementation of LoraPhy's pure virtual functions + virtual void EndReceive(Ptr packet, Ptr event) = 0; + + // Implementation of LoraPhy's pure virtual functions + virtual void Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm) = 0; + + // Implementation of LoraPhy's pure virtual functions + virtual bool IsOnFrequency(double frequencyMHz); + + // Implementation of LoraPhy's pure virtual functions + virtual bool IsTransmitting(void); /** - * The PHY layer is in STANDBY. - * When the PHY is in this state, it's listening to the channel, and - * it's also ready to transmit data passed to it by the MAC layer. + * Set the frequency this EndDevice will listen on. + * + * Should a packet be transmitted on a frequency different than that the + * EndDeviceLoraPhy is listening on, the packet will be discarded. + * + * \param The frequency [MHz] to listen to. */ - STANDBY, + void SetFrequency(double frequencyMHz); /** - * The PHY layer is sending a packet. - * During transmission, the device cannot receive any packet or send - * any additional packet. + * Set the Spreading Factor this EndDevice will listen for. + * + * The EndDeviceLoraPhy object will not be able to lock on transmissions that + * use a different SF than the one it's listening for. + * + * \param sf The spreading factor to listen for. */ - TX, + void SetSpreadingFactor(uint8_t sf); /** - * The PHY layer is receiving a packet. - * While the device is locked on an incoming packet, transmission is - * not possible. + * Get the Spreading Factor this EndDevice is listening for. + * + * \return The Spreading Factor we are listening for. */ - RX - }; - - static TypeId GetTypeId (void); - - // Constructor and destructor - EndDeviceLoraPhy (); - virtual ~EndDeviceLoraPhy (); - - // Implementation of LoraPhy's pure virtual functions - virtual void StartReceive (Ptr packet, double rxPowerDbm, - uint8_t sf, Time duration, double frequencyMHz) = 0; - - // Implementation of LoraPhy's pure virtual functions - virtual void EndReceive (Ptr packet, - Ptr event) = 0; - - // Implementation of LoraPhy's pure virtual functions - virtual void Send (Ptr packet, LoraTxParameters txParams, - double frequencyMHz, double txPowerDbm) = 0; - - // Implementation of LoraPhy's pure virtual functions - virtual bool IsOnFrequency (double frequencyMHz); - - // Implementation of LoraPhy's pure virtual functions - virtual bool IsTransmitting (void); - - /** - * Set the frequency this EndDevice will listen on. - * - * Should a packet be transmitted on a frequency different than that the - * EndDeviceLoraPhy is listening on, the packet will be discarded. - * - * \param The frequency [MHz] to listen to. - */ - void SetFrequency (double frequencyMHz); - - /** - * Set the Spreading Factor this EndDevice will listen for. - * - * The EndDeviceLoraPhy object will not be able to lock on transmissions that - * use a different SF than the one it's listening for. - * - * \param sf The spreading factor to listen for. - */ - void SetSpreadingFactor (uint8_t sf); - - /** - * Get the Spreading Factor this EndDevice is listening for. - * - * \return The Spreading Factor we are listening for. - */ - uint8_t GetSpreadingFactor (void); - - /** - * Return the state this End Device is currently in. - * - * \return The state this EndDeviceLoraPhy is currently in. - */ - EndDeviceLoraPhy::State GetState (void); - - /** - * Switch to the STANDBY state. - */ - void SwitchToStandby (void); - - /** - * Switch to the SLEEP state. - */ - void SwitchToSleep (void); - - /** - * Add the input listener to the list of objects to be notified of PHY-level - * events. - * - * \param listener the new listener - */ - void RegisterListener (EndDeviceLoraPhyListener *listener); - - /** - * Remove the input listener from the list of objects to be notified of - * PHY-level events. - * - * \param listener the listener to be unregistered - */ - void UnregisterListener (EndDeviceLoraPhyListener *listener); - - static const double sensitivity[6]; //!< The sensitivity vector of this device to different SFs - - -protected: - /** - * Switch to the RX state - */ - void SwitchToRx (); - - /** - * Switch to the TX state - */ - void SwitchToTx (double txPowerDbm); - - /** - * Trace source for when a packet is lost because it was using a SF different from - * the one this EndDeviceLoraPhy was configured to listen for. - */ - TracedCallback, uint32_t> m_wrongSf; - - /** - * Trace source for when a packet is lost because it was transmitted on a - * frequency different from the one this EndDeviceLoraPhy was configured to - * listen on. - */ - TracedCallback, uint32_t> m_wrongFrequency; - - TracedValue m_state; //!< The state this PHY is currently in. - - // static const double sensitivity[6]; //!< The sensitivity vector of this device to different SFs - - double m_frequency; //!< The frequency this device is listening on - - uint8_t m_sf; //!< The Spreading Factor this device is listening for - - /** - * typedef for a list of EndDeviceLoraPhyListener - */ - typedef std::vector Listeners; - /** - * typedef for a list of EndDeviceLoraPhyListener iterator - */ - typedef std::vector::iterator ListenersI; - - Listeners m_listeners; //!< PHY listeners + uint8_t GetSpreadingFactor(void); + + /** + * Return the state this End Device is currently in. + * + * \return The state this EndDeviceLoraPhy is currently in. + */ + EndDeviceLoraPhy::State GetState(void); + + /** + * Switch to the STANDBY state. + */ + void SwitchToStandby(void); + + /** + * Switch to the SLEEP state. + */ + void SwitchToSleep(void); + + /** + * Add the input listener to the list of objects to be notified of PHY-level + * events. + * + * \param listener the new listener + */ + void RegisterListener(EndDeviceLoraPhyListener* listener); + + /** + * Remove the input listener from the list of objects to be notified of + * PHY-level events. + * + * \param listener the listener to be unregistered + */ + void UnregisterListener(EndDeviceLoraPhyListener* listener); + + static const double sensitivity[6]; //!< The sensitivity vector of this device to different SFs + + protected: + /** + * Switch to the RX state + */ + void SwitchToRx(); + + /** + * Switch to the TX state + */ + void SwitchToTx(double txPowerDbm); + + /** + * Trace source for when a packet is lost because it was using a SF different from + * the one this EndDeviceLoraPhy was configured to listen for. + */ + TracedCallback, uint32_t> m_wrongSf; + + /** + * Trace source for when a packet is lost because it was transmitted on a + * frequency different from the one this EndDeviceLoraPhy was configured to + * listen on. + */ + TracedCallback, uint32_t> m_wrongFrequency; + + TracedValue m_state; //!< The state this PHY is currently in. + + // static const double sensitivity[6]; //!< The sensitivity vector of this device to different + // SFs + + double m_frequency; //!< The frequency this device is listening on + + uint8_t m_sf; //!< The Spreading Factor this device is listening for + + /** + * typedef for a list of EndDeviceLoraPhyListener + */ + typedef std::vector Listeners; + /** + * typedef for a list of EndDeviceLoraPhyListener iterator + */ + typedef std::vector::iterator ListenersI; + + Listeners m_listeners; //!< PHY listeners }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* END_DEVICE_LORA_PHY_H */ diff --git a/model/end-device-lorawan-mac.cc b/model/end-device-lorawan-mac.cc index aa06d0f9d6..ac940d77b9 100644 --- a/model/end-device-lorawan-mac.cc +++ b/model/end-device-lorawan-mac.cc @@ -21,131 +21,131 @@ * Modified by: Peggy Anderson */ -#include "ns3/end-device-lorawan-mac.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/end-device-lora-phy.h" -#include "ns3/simulator.h" +#include "end-device-lorawan-mac.h" + +#include "class-a-end-device-lorawan-mac.h" +#include "end-device-lora-phy.h" + #include "ns3/log.h" +#include "ns3/simulator.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("EndDeviceLorawanMac"); +NS_LOG_COMPONENT_DEFINE("EndDeviceLorawanMac"); -NS_OBJECT_ENSURE_REGISTERED (EndDeviceLorawanMac); +NS_OBJECT_ENSURE_REGISTERED(EndDeviceLorawanMac); TypeId -EndDeviceLorawanMac::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::EndDeviceLorawanMac") - .SetParent () - .SetGroupName ("lorawan") - .AddTraceSource ("RequiredTransmissions", - "Total number of transmissions required to deliver this packet", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_requiredTxCallback), - "ns3::TracedValueCallback::uint8_t") - .AddAttribute ("DataRate", - "Data Rate currently employed by this end device", - UintegerValue (0), - MakeUintegerAccessor (&EndDeviceLorawanMac::m_dataRate), - MakeUintegerChecker (0, 5)) - .AddTraceSource ("DataRate", - "Data Rate currently employed by this end device", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_dataRate), - "ns3::TracedValueCallback::uint8_t") - .AddAttribute ("DRControl", - "Whether to request the NS to control this device's Data Rate", - BooleanValue (), - MakeBooleanAccessor (&EndDeviceLorawanMac::m_controlDataRate), - MakeBooleanChecker ()) - .AddTraceSource ("TxPower", - "Transmission power currently employed by this end device", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_txPower), - "ns3::TracedValueCallback::Double") - .AddTraceSource ("LastKnownLinkMargin", - "Last known demodulation margin in " - "communications between this end device " - "and a gateway", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_lastKnownLinkMargin), - "ns3::TracedValueCallback::Double") - .AddTraceSource ("LastKnownGatewayCount", - "Last known number of gateways able to " - "listen to this end device", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_lastKnownGatewayCount), - "ns3::TracedValueCallback::Int") - .AddTraceSource ("AggregatedDutyCycle", - "Aggregate duty cycle, in fraction form, " - "this end device must respect", - MakeTraceSourceAccessor - (&EndDeviceLorawanMac::m_aggregatedDutyCycle), - "ns3::TracedValueCallback::Double") - .AddAttribute ("MaxTransmissions", - "Maximum number of transmissions for a packet", - IntegerValue (8), - MakeIntegerAccessor (&EndDeviceLorawanMac::m_maxNumbTx), - MakeIntegerChecker ()) - .AddAttribute ("EnableEDDataRateAdaptation", - "Whether the End Device should up its Data Rate " - "in case it doesn't get a reply from the NS.", - BooleanValue (false), - MakeBooleanAccessor (&EndDeviceLorawanMac::m_enableDRAdapt), - MakeBooleanChecker ()) - .AddAttribute ("MType", - "Specify type of message will be sent by this ED.", - EnumValue (LorawanMacHeader::UNCONFIRMED_DATA_UP), - MakeEnumAccessor (&EndDeviceLorawanMac::m_mType), - MakeEnumChecker (LorawanMacHeader::UNCONFIRMED_DATA_UP, - "Unconfirmed", - LorawanMacHeader::CONFIRMED_DATA_UP, - "Confirmed")) - .AddConstructor (); - return tid; -} - -EndDeviceLorawanMac::EndDeviceLorawanMac () - : m_enableDRAdapt (false), - m_maxNumbTx (8), - m_dataRate (0), - m_txPower (14), - m_codingRate (1), +EndDeviceLorawanMac::GetTypeId(void) +{ + static TypeId tid = + TypeId("ns3::EndDeviceLorawanMac") + .SetParent() + .SetGroupName("lorawan") + .AddTraceSource("RequiredTransmissions", + "Total number of transmissions required to deliver this packet", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_requiredTxCallback), + "ns3::TracedValueCallback::uint8_t") + .AddAttribute("DataRate", + "Data Rate currently employed by this end device", + UintegerValue(0), + MakeUintegerAccessor(&EndDeviceLorawanMac::m_dataRate), + MakeUintegerChecker(0, 5)) + .AddTraceSource("DataRate", + "Data Rate currently employed by this end device", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_dataRate), + "ns3::TracedValueCallback::uint8_t") + .AddAttribute("DRControl", + "Whether to request the NS to control this device's Data Rate", + BooleanValue(), + MakeBooleanAccessor(&EndDeviceLorawanMac::m_controlDataRate), + MakeBooleanChecker()) + .AddTraceSource("TxPower", + "Transmission power currently employed by this end device", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_txPower), + "ns3::TracedValueCallback::Double") + .AddTraceSource("LastKnownLinkMargin", + "Last known demodulation margin in " + "communications between this end device " + "and a gateway", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_lastKnownLinkMargin), + "ns3::TracedValueCallback::Double") + .AddTraceSource("LastKnownGatewayCount", + "Last known number of gateways able to " + "listen to this end device", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_lastKnownGatewayCount), + "ns3::TracedValueCallback::Int") + .AddTraceSource("AggregatedDutyCycle", + "Aggregate duty cycle, in fraction form, " + "this end device must respect", + MakeTraceSourceAccessor(&EndDeviceLorawanMac::m_aggregatedDutyCycle), + "ns3::TracedValueCallback::Double") + .AddAttribute("MaxTransmissions", + "Maximum number of transmissions for a packet", + IntegerValue(8), + MakeIntegerAccessor(&EndDeviceLorawanMac::m_maxNumbTx), + MakeIntegerChecker()) + .AddAttribute("EnableEDDataRateAdaptation", + "Whether the End Device should up its Data Rate " + "in case it doesn't get a reply from the NS.", + BooleanValue(false), + MakeBooleanAccessor(&EndDeviceLorawanMac::m_enableDRAdapt), + MakeBooleanChecker()) + .AddAttribute("MType", + "Specify type of message will be sent by this ED.", + EnumValue(LorawanMacHeader::UNCONFIRMED_DATA_UP), + MakeEnumAccessor(&EndDeviceLorawanMac::m_mType), + MakeEnumChecker(LorawanMacHeader::UNCONFIRMED_DATA_UP, + "Unconfirmed", + LorawanMacHeader::CONFIRMED_DATA_UP, + "Confirmed")) + .AddConstructor(); + return tid; +} + +EndDeviceLorawanMac::EndDeviceLorawanMac() + : m_enableDRAdapt(false), + m_maxNumbTx(8), + m_dataRate(0), + m_txPower(14), + m_codingRate(1), // LoraWAN default - m_headerDisabled (0), + m_headerDisabled(0), // LoraWAN default - m_address (LoraDeviceAddress (0)), + m_address(LoraDeviceAddress(0)), // LoraWAN default - m_receiveWindowDurationInSymbols (8), + m_receiveWindowDurationInSymbols(8), // LoraWAN default - m_controlDataRate (false), - m_lastKnownLinkMargin (0), - m_lastKnownGatewayCount (0), - m_aggregatedDutyCycle (1), - m_mType (LorawanMacHeader::CONFIRMED_DATA_UP), - m_currentFCnt (0) + m_controlDataRate(false), + m_lastKnownLinkMargin(0), + m_lastKnownGatewayCount(0), + m_aggregatedDutyCycle(1), + m_mType(LorawanMacHeader::CONFIRMED_DATA_UP), + m_currentFCnt(0) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Initialize the random variable we'll use to decide which channel to - // transmit on. - m_uniformRV = CreateObject (); + // Initialize the random variable we'll use to decide which channel to + // transmit on. + m_uniformRV = CreateObject(); - // Void the transmission event - m_nextTx = EventId (); - m_nextTx.Cancel (); + // Void the transmission event + m_nextTx = EventId(); + m_nextTx.Cancel(); - // Initialize structure for retransmission parameters - m_retxParams = EndDeviceLorawanMac::LoraRetxParameters (); - m_retxParams.retxLeft = m_maxNumbTx; + // Initialize structure for retransmission parameters + m_retxParams = EndDeviceLorawanMac::LoraRetxParameters(); + m_retxParams.retxLeft = m_maxNumbTx; } -EndDeviceLorawanMac::~EndDeviceLorawanMac () +EndDeviceLorawanMac::~EndDeviceLorawanMac() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } //////////////////////// @@ -153,782 +153,788 @@ EndDeviceLorawanMac::~EndDeviceLorawanMac () //////////////////////// void -EndDeviceLorawanMac::Send (Ptr packet) +EndDeviceLorawanMac::Send(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // If it is not possible to transmit now because of the duty cycle, - // or because we are receiving, schedule a tx/retx later + // If it is not possible to transmit now because of the duty cycle, + // or because we are receiving, schedule a tx/retx later - Time netxTxDelay = GetNextTransmissionDelay (); - if (netxTxDelay != Seconds (0)) + Time netxTxDelay = GetNextTransmissionDelay(); + if (netxTxDelay != Seconds(0)) { - postponeTransmission (netxTxDelay, packet); - return; + postponeTransmission(netxTxDelay, packet); + return; } - // Pick a channel on which to transmit the packet - Ptr txChannel = GetChannelForTx (); + // Pick a channel on which to transmit the packet + Ptr txChannel = GetChannelForTx(); - if (!(txChannel && m_retxParams.retxLeft > 0)) + if (!(txChannel && m_retxParams.retxLeft > 0)) { - if (!txChannel) + if (!txChannel) { - m_cannotSendBecauseDutyCycle (packet); + m_cannotSendBecauseDutyCycle(packet); } - else + else { - NS_LOG_INFO ("Max number of transmission achieved: packet not transmitted."); + NS_LOG_INFO("Max number of transmission achieved: packet not transmitted."); } } - else - // the transmitting channel is available and we have not run out the maximum number of retransmissions + else + // the transmitting channel is available and we have not run out the maximum number of + // retransmissions { - // Make sure we can transmit at the current power on this channel - NS_ASSERT_MSG (m_txPower <= m_channelHelper.GetTxPowerForChannel (txChannel), - " The selected power is too hight to be supported by this channel."); - DoSend (packet); + // Make sure we can transmit at the current power on this channel + NS_ASSERT_MSG(m_txPower <= m_channelHelper.GetTxPowerForChannel(txChannel), + " The selected power is too hight to be supported by this channel."); + DoSend(packet); } } void -EndDeviceLorawanMac::postponeTransmission (Time netxTxDelay, Ptr packet) +EndDeviceLorawanMac::postponeTransmission(Time netxTxDelay, Ptr packet) { - NS_LOG_FUNCTION (this); - // Delete previously scheduled transmissions if any. - Simulator::Cancel (m_nextTx); - m_nextTx = Simulator::Schedule (netxTxDelay, &EndDeviceLorawanMac::DoSend, this, packet); - NS_LOG_WARN ("Attempting to send, but the aggregate duty cycle won't allow it. Scheduling a tx at a delay " - << netxTxDelay.GetSeconds () << "."); + NS_LOG_FUNCTION(this); + // Delete previously scheduled transmissions if any. + Simulator::Cancel(m_nextTx); + m_nextTx = Simulator::Schedule(netxTxDelay, &EndDeviceLorawanMac::DoSend, this, packet); + NS_LOG_WARN("Attempting to send, but the aggregate duty cycle won't allow it. Scheduling a tx " + "at a delay " + << netxTxDelay.GetSeconds() << "."); } - void -EndDeviceLorawanMac::DoSend (Ptr packet) +EndDeviceLorawanMac::DoSend(Ptr packet) { - NS_LOG_FUNCTION (this); - // Checking if this is the transmission of a new packet - if (packet != m_retxParams.packet) + NS_LOG_FUNCTION(this); + // Checking if this is the transmission of a new packet + if (packet != m_retxParams.packet) { - NS_LOG_DEBUG ("Received a new packet from application. Resetting retransmission parameters."); - m_currentFCnt++; - NS_LOG_DEBUG ("APP packet: " << packet << "."); + NS_LOG_DEBUG( + "Received a new packet from application. Resetting retransmission parameters."); + m_currentFCnt++; + NS_LOG_DEBUG("APP packet: " << packet << "."); - // Add the Lora Frame Header to the packet - LoraFrameHeader frameHdr; - ApplyNecessaryOptions (frameHdr); - packet->AddHeader (frameHdr); + // Add the Lora Frame Header to the packet + LoraFrameHeader frameHdr; + ApplyNecessaryOptions(frameHdr); + packet->AddHeader(frameHdr); - NS_LOG_INFO ("Added frame header of size " << frameHdr.GetSerializedSize () << - " bytes."); + NS_LOG_INFO("Added frame header of size " << frameHdr.GetSerializedSize() << " bytes."); - // Check that MACPayload length is below the allowed maximum - if (packet->GetSize () > m_maxAppPayloadForDataRate.at (m_dataRate)) + // Check that MACPayload length is below the allowed maximum + if (packet->GetSize() > m_maxAppPayloadForDataRate.at(m_dataRate)) { - NS_LOG_WARN ("Attempting to send a packet larger than the maximum allowed" - << " size at this DataRate (DR" << unsigned(m_dataRate) << - "). Transmission canceled."); - return; + NS_LOG_WARN("Attempting to send a packet larger than the maximum allowed" + << " size at this DataRate (DR" << unsigned(m_dataRate) + << "). Transmission canceled."); + return; } + // Add the Lora Mac header to the packet + LorawanMacHeader macHdr; + ApplyNecessaryOptions(macHdr); + packet->AddHeader(macHdr); - // Add the Lora Mac header to the packet - LorawanMacHeader macHdr; - ApplyNecessaryOptions (macHdr); - packet->AddHeader (macHdr); - - // Reset MAC command list - m_macCommandList.clear (); + // Reset MAC command list + m_macCommandList.clear(); - if (m_retxParams.waitingAck) + if (m_retxParams.waitingAck) { - // Call the callback to notify about the failure - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, false, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG (" Received new packet from the application layer: stopping retransmission procedure. Used " << - unsigned(txs) << " transmissions out of a maximum of " << unsigned(m_maxNumbTx) << "."); + // Call the callback to notify about the failure + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, false, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_DEBUG(" Received new packet from the application layer: stopping retransmission " + "procedure. Used " + << unsigned(txs) << " transmissions out of a maximum of " + << unsigned(m_maxNumbTx) << "."); } - // Reset retransmission parameters - resetRetransmissionParameters (); + // Reset retransmission parameters + resetRetransmissionParameters(); - // If this is the first transmission of a confirmed packet, save parameters for the (possible) next retransmissions. - if (m_mType == LorawanMacHeader::CONFIRMED_DATA_UP) + // If this is the first transmission of a confirmed packet, save parameters for the + // (possible) next retransmissions. + if (m_mType == LorawanMacHeader::CONFIRMED_DATA_UP) { - m_retxParams.packet = packet->Copy (); - m_retxParams.retxLeft = m_maxNumbTx; - m_retxParams.waitingAck = true; - m_retxParams.firstAttempt = Simulator::Now (); - m_retxParams.retxLeft = m_retxParams.retxLeft - 1; // decreasing the number of retransmissions + m_retxParams.packet = packet->Copy(); + m_retxParams.retxLeft = m_maxNumbTx; + m_retxParams.waitingAck = true; + m_retxParams.firstAttempt = Simulator::Now(); + m_retxParams.retxLeft = + m_retxParams.retxLeft - 1; // decreasing the number of retransmissions - NS_LOG_DEBUG ("Message type is " << m_mType); - NS_LOG_DEBUG ("It is a confirmed packet. Setting retransmission parameters and decreasing the number of transmissions left."); + NS_LOG_DEBUG("Message type is " << m_mType); + NS_LOG_DEBUG("It is a confirmed packet. Setting retransmission parameters and " + "decreasing the number of transmissions left."); - NS_LOG_INFO ("Added MAC header of size " << macHdr.GetSerializedSize () << - " bytes."); + NS_LOG_INFO("Added MAC header of size " << macHdr.GetSerializedSize() << " bytes."); - // Sent a new packet - NS_LOG_DEBUG ("Copied packet: " << m_retxParams.packet); - m_sentNewPacket (m_retxParams.packet); + // Sent a new packet + NS_LOG_DEBUG("Copied packet: " << m_retxParams.packet); + m_sentNewPacket(m_retxParams.packet); - // static_cast(this)->SendToPhy (m_retxParams.packet); - SendToPhy (m_retxParams.packet); + // static_cast(this)->SendToPhy (m_retxParams.packet); + SendToPhy(m_retxParams.packet); } - else + else { - m_sentNewPacket (packet); - // static_cast(this)->SendToPhy (packet); - SendToPhy (packet); + m_sentNewPacket(packet); + // static_cast(this)->SendToPhy (packet); + SendToPhy(packet); } - } - // this is a retransmission - else + // this is a retransmission + else { - if (m_retxParams.waitingAck) + if (m_retxParams.waitingAck) { - - // Remove the headers - LorawanMacHeader macHdr; - LoraFrameHeader frameHdr; - packet->RemoveHeader(macHdr); - packet->RemoveHeader(frameHdr); - - // Add the Lora Frame Header to the packet - frameHdr = LoraFrameHeader (); - ApplyNecessaryOptions (frameHdr); - packet->AddHeader (frameHdr); - - NS_LOG_INFO ("Added frame header of size " << frameHdr.GetSerializedSize () << - " bytes."); - - // Add the Lorawan Mac header to the packet - macHdr = LorawanMacHeader (); - ApplyNecessaryOptions (macHdr); - packet->AddHeader (macHdr); - m_retxParams.retxLeft = m_retxParams.retxLeft - 1; // decreasing the number of retransmissions - NS_LOG_DEBUG ("Retransmitting an old packet."); - - // static_cast(this)->SendToPhy (m_retxParams.packet); - SendToPhy (m_retxParams.packet); + // Remove the headers + LorawanMacHeader macHdr; + LoraFrameHeader frameHdr; + packet->RemoveHeader(macHdr); + packet->RemoveHeader(frameHdr); + + // Add the Lora Frame Header to the packet + frameHdr = LoraFrameHeader(); + ApplyNecessaryOptions(frameHdr); + packet->AddHeader(frameHdr); + + NS_LOG_INFO("Added frame header of size " << frameHdr.GetSerializedSize() << " bytes."); + + // Add the Lorawan Mac header to the packet + macHdr = LorawanMacHeader(); + ApplyNecessaryOptions(macHdr); + packet->AddHeader(macHdr); + m_retxParams.retxLeft = + m_retxParams.retxLeft - 1; // decreasing the number of retransmissions + NS_LOG_DEBUG("Retransmitting an old packet."); + + // static_cast(this)->SendToPhy (m_retxParams.packet); + SendToPhy(m_retxParams.packet); } } - } void -EndDeviceLorawanMac::SendToPhy (Ptr packet) -{ } +EndDeviceLorawanMac::SendToPhy(Ptr packet) +{ +} ////////////////////////// // Receiving methods // ////////////////////////// void -EndDeviceLorawanMac::Receive (Ptr packet) -{ } +EndDeviceLorawanMac::Receive(Ptr packet) +{ +} void -EndDeviceLorawanMac::FailedReception (Ptr packet) -{ } +EndDeviceLorawanMac::FailedReception(Ptr packet) +{ +} void -EndDeviceLorawanMac::ParseCommands (LoraFrameHeader frameHeader) +EndDeviceLorawanMac::ParseCommands(LoraFrameHeader frameHeader) { - NS_LOG_FUNCTION (this << frameHeader); + NS_LOG_FUNCTION(this << frameHeader); - if (m_retxParams.waitingAck) + if (m_retxParams.waitingAck) { - if (frameHeader.GetAck ()) + if (frameHeader.GetAck()) { - NS_LOG_INFO ("The message is an ACK, not waiting for it anymore."); - - NS_LOG_DEBUG ("Reset retransmission variables to default values and cancel retransmission if already scheduled."); + NS_LOG_INFO("The message is an ACK, not waiting for it anymore."); - uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); - m_requiredTxCallback (txs, true, m_retxParams.firstAttempt, m_retxParams.packet); - NS_LOG_DEBUG ("Received ACK packet after " << unsigned(txs) << " transmissions: stopping retransmission procedure. "); + NS_LOG_DEBUG("Reset retransmission variables to default values and cancel " + "retransmission if already scheduled."); - // Reset retransmission parameters - resetRetransmissionParameters (); + uint8_t txs = m_maxNumbTx - (m_retxParams.retxLeft); + m_requiredTxCallback(txs, true, m_retxParams.firstAttempt, m_retxParams.packet); + NS_LOG_DEBUG("Received ACK packet after " + << unsigned(txs) << " transmissions: stopping retransmission procedure. "); + // Reset retransmission parameters + resetRetransmissionParameters(); } - else + else { - NS_LOG_ERROR ("Received downlink message not containing an ACK while we were waiting for it!"); + NS_LOG_ERROR( + "Received downlink message not containing an ACK while we were waiting for it!"); } } - std::list > commands = frameHeader.GetCommands (); - std::list >::iterator it; - for (it = commands.begin (); it != commands.end (); it++) + std::list> commands = frameHeader.GetCommands(); + std::list>::iterator it; + for (it = commands.begin(); it != commands.end(); it++) { - NS_LOG_DEBUG ("Iterating over the MAC commands..."); - enum MacCommandType type = (*it)->GetCommandType (); - switch (type) + NS_LOG_DEBUG("Iterating over the MAC commands..."); + enum MacCommandType type = (*it)->GetCommandType(); + switch (type) { - case (LINK_CHECK_ANS): - { - NS_LOG_DEBUG ("Detected a LinkCheckAns command."); + case (LINK_CHECK_ANS): { + NS_LOG_DEBUG("Detected a LinkCheckAns command."); // Cast the command - Ptr linkCheckAns = (*it)->GetObject (); + Ptr linkCheckAns = (*it)->GetObject(); // Call the appropriate function to take action - OnLinkCheckAns (linkCheckAns->GetMargin (), linkCheckAns->GetGwCnt ()); + OnLinkCheckAns(linkCheckAns->GetMargin(), linkCheckAns->GetGwCnt()); break; - } - case (LINK_ADR_REQ): - { - NS_LOG_DEBUG ("Detected a LinkAdrReq command."); + } + case (LINK_ADR_REQ): { + NS_LOG_DEBUG("Detected a LinkAdrReq command."); // Cast the command - Ptr linkAdrReq = (*it)->GetObject (); + Ptr linkAdrReq = (*it)->GetObject(); // Call the appropriate function to take action - OnLinkAdrReq (linkAdrReq->GetDataRate (), linkAdrReq->GetTxPower (), - linkAdrReq->GetEnabledChannelsList (), - linkAdrReq->GetRepetitions ()); + OnLinkAdrReq(linkAdrReq->GetDataRate(), + linkAdrReq->GetTxPower(), + linkAdrReq->GetEnabledChannelsList(), + linkAdrReq->GetRepetitions()); break; - } - case (DUTY_CYCLE_REQ): - { - NS_LOG_DEBUG ("Detected a DutyCycleReq command."); + } + case (DUTY_CYCLE_REQ): { + NS_LOG_DEBUG("Detected a DutyCycleReq command."); // Cast the command - Ptr dutyCycleReq = (*it)->GetObject (); + Ptr dutyCycleReq = (*it)->GetObject(); // Call the appropriate function to take action - OnDutyCycleReq (dutyCycleReq->GetMaximumAllowedDutyCycle ()); + OnDutyCycleReq(dutyCycleReq->GetMaximumAllowedDutyCycle()); break; - } - case (RX_PARAM_SETUP_REQ): - { - NS_LOG_DEBUG ("Detected a RxParamSetupReq command."); + } + case (RX_PARAM_SETUP_REQ): { + NS_LOG_DEBUG("Detected a RxParamSetupReq command."); // Cast the command - Ptr rxParamSetupReq = (*it)->GetObject (); + Ptr rxParamSetupReq = (*it)->GetObject(); // Call the appropriate function to take action - OnRxParamSetupReq (rxParamSetupReq); + OnRxParamSetupReq(rxParamSetupReq); break; - } - case (DEV_STATUS_REQ): - { - NS_LOG_DEBUG ("Detected a DevStatusReq command."); + } + case (DEV_STATUS_REQ): { + NS_LOG_DEBUG("Detected a DevStatusReq command."); // Cast the command - Ptr devStatusReq = (*it)->GetObject (); + Ptr devStatusReq = (*it)->GetObject(); // Call the appropriate function to take action - OnDevStatusReq (); + OnDevStatusReq(); break; - } - case (NEW_CHANNEL_REQ): - { - NS_LOG_DEBUG ("Detected a NewChannelReq command."); + } + case (NEW_CHANNEL_REQ): { + NS_LOG_DEBUG("Detected a NewChannelReq command."); // Cast the command - Ptr newChannelReq = (*it)->GetObject (); + Ptr newChannelReq = (*it)->GetObject(); // Call the appropriate function to take action - OnNewChannelReq (newChannelReq->GetChannelIndex (), newChannelReq->GetFrequency (), newChannelReq->GetMinDataRate (), newChannelReq->GetMaxDataRate ()); + OnNewChannelReq(newChannelReq->GetChannelIndex(), + newChannelReq->GetFrequency(), + newChannelReq->GetMinDataRate(), + newChannelReq->GetMaxDataRate()); break; - } - case (RX_TIMING_SETUP_REQ): - { + } + case (RX_TIMING_SETUP_REQ): { break; - } - case (TX_PARAM_SETUP_REQ): - { + } + case (TX_PARAM_SETUP_REQ): { break; - } - case (DL_CHANNEL_REQ): - { + } + case (DL_CHANNEL_REQ): { break; - } - default: - { - NS_LOG_ERROR ("CID not recognized"); + } + default: { + NS_LOG_ERROR("CID not recognized"); break; - } + } } } - } void -EndDeviceLorawanMac::ApplyNecessaryOptions (LoraFrameHeader& frameHeader) +EndDeviceLorawanMac::ApplyNecessaryOptions(LoraFrameHeader& frameHeader) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - frameHeader.SetAsUplink (); - frameHeader.SetFPort (1); // TODO Use an appropriate frame port based on the application - frameHeader.SetAddress (m_address); - frameHeader.SetAdr (m_controlDataRate); - frameHeader.SetAdrAckReq (0); // TODO Set ADRACKREQ if a member variable is true + frameHeader.SetAsUplink(); + frameHeader.SetFPort(1); // TODO Use an appropriate frame port based on the application + frameHeader.SetAddress(m_address); + frameHeader.SetAdr(m_controlDataRate); + frameHeader.SetAdrAckReq(0); // TODO Set ADRACKREQ if a member variable is true - // FPending does not exist in uplink messages - frameHeader.SetFCnt (m_currentFCnt); + // FPending does not exist in uplink messages + frameHeader.SetFCnt(m_currentFCnt); - // Add listed MAC commands - for (const auto &command : m_macCommandList) + // Add listed MAC commands + for (const auto& command : m_macCommandList) { - NS_LOG_INFO ("Applying a MAC Command of CID " << - unsigned(MacCommand::GetCIDFromMacCommand - (command->GetCommandType ()))); + NS_LOG_INFO("Applying a MAC Command of CID " + << unsigned(MacCommand::GetCIDFromMacCommand(command->GetCommandType()))); - frameHeader.AddCommand (command); + frameHeader.AddCommand(command); } - } void -EndDeviceLorawanMac::ApplyNecessaryOptions (LorawanMacHeader& macHeader) +EndDeviceLorawanMac::ApplyNecessaryOptions(LorawanMacHeader& macHeader) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - macHeader.SetMType (m_mType); - macHeader.SetMajor (1); + macHeader.SetMType(m_mType); + macHeader.SetMajor(1); } void -EndDeviceLorawanMac::SetMType (LorawanMacHeader::MType mType) +EndDeviceLorawanMac::SetMType(LorawanMacHeader::MType mType) { - m_mType = mType; - NS_LOG_DEBUG ("Message type is set to " << mType); + m_mType = mType; + NS_LOG_DEBUG("Message type is set to " << mType); } LorawanMacHeader::MType -EndDeviceLorawanMac::GetMType (void) +EndDeviceLorawanMac::GetMType(void) { - return m_mType; + return m_mType; } void -EndDeviceLorawanMac::TxFinished (Ptr packet) -{ } +EndDeviceLorawanMac::TxFinished(Ptr packet) +{ +} Time -EndDeviceLorawanMac::GetNextClassTransmissionDelay (Time waitingTime) +EndDeviceLorawanMac::GetNextClassTransmissionDelay(Time waitingTime) { - NS_LOG_FUNCTION_NOARGS (); - return waitingTime; + NS_LOG_FUNCTION_NOARGS(); + return waitingTime; } Time -EndDeviceLorawanMac::GetNextTransmissionDelay (void) +EndDeviceLorawanMac::GetNextTransmissionDelay(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Check duty cycle // + // Check duty cycle // - // Pick a random channel to transmit on - std::vector > logicalChannels; - logicalChannels = m_channelHelper.GetEnabledChannelList (); // Use a separate list to do the shuffle - //logicalChannels = Shuffle (logicalChannels); + // Pick a random channel to transmit on + std::vector> logicalChannels; + logicalChannels = + m_channelHelper.GetEnabledChannelList(); // Use a separate list to do the shuffle + // logicalChannels = Shuffle (logicalChannels); + Time waitingTime = Time::Max(); - Time waitingTime = Time::Max (); - - // Try every channel - std::vector >::iterator it; - for (it = logicalChannels.begin (); it != logicalChannels.end (); ++it) + // Try every channel + std::vector>::iterator it; + for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it) { - // Pointer to the current channel - Ptr logicalChannel = *it; - double frequency = logicalChannel->GetFrequency (); + // Pointer to the current channel + Ptr logicalChannel = *it; + double frequency = logicalChannel->GetFrequency(); - waitingTime = std::min (waitingTime, m_channelHelper.GetWaitingTime (logicalChannel)); + waitingTime = std::min(waitingTime, m_channelHelper.GetWaitingTime(logicalChannel)); - NS_LOG_DEBUG ("Waiting time before the next transmission in channel with frequecy " << - frequency << " is = " << waitingTime.GetSeconds () << "."); + NS_LOG_DEBUG("Waiting time before the next transmission in channel with frequecy " + << frequency << " is = " << waitingTime.GetSeconds() << "."); } - waitingTime = GetNextClassTransmissionDelay (waitingTime); + waitingTime = GetNextClassTransmissionDelay(waitingTime); - return waitingTime; + return waitingTime; } Ptr -EndDeviceLorawanMac::GetChannelForTx (void) +EndDeviceLorawanMac::GetChannelForTx(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Pick a random channel to transmit on - std::vector > logicalChannels; - logicalChannels = m_channelHelper.GetEnabledChannelList (); // Use a separate list to do the shuffle - logicalChannels = Shuffle (logicalChannels); + // Pick a random channel to transmit on + std::vector> logicalChannels; + logicalChannels = + m_channelHelper.GetEnabledChannelList(); // Use a separate list to do the shuffle + logicalChannels = Shuffle(logicalChannels); - // Try every channel - std::vector >::iterator it; - for (it = logicalChannels.begin (); it != logicalChannels.end (); ++it) + // Try every channel + std::vector>::iterator it; + for (it = logicalChannels.begin(); it != logicalChannels.end(); ++it) { - // Pointer to the current channel - Ptr logicalChannel = *it; - double frequency = logicalChannel->GetFrequency (); + // Pointer to the current channel + Ptr logicalChannel = *it; + double frequency = logicalChannel->GetFrequency(); - NS_LOG_DEBUG ("Frequency of the current channel: " << frequency); + NS_LOG_DEBUG("Frequency of the current channel: " << frequency); - // Verify that we can send the packet - Time waitingTime = m_channelHelper.GetWaitingTime (logicalChannel); + // Verify that we can send the packet + Time waitingTime = m_channelHelper.GetWaitingTime(logicalChannel); - NS_LOG_DEBUG ("Waiting time for current channel = " << - waitingTime.GetSeconds ()); + NS_LOG_DEBUG("Waiting time for current channel = " << waitingTime.GetSeconds()); - // Send immediately if we can - if (waitingTime == Seconds (0)) + // Send immediately if we can + if (waitingTime == Seconds(0)) { - return *it; + return *it; } - else + else { - NS_LOG_DEBUG ("Packet cannot be immediately transmitted on " << - "the current channel because of duty cycle limitations."); + NS_LOG_DEBUG("Packet cannot be immediately transmitted on " + << "the current channel because of duty cycle limitations."); } } - return 0; // In this case, no suitable channel was found + return 0; // In this case, no suitable channel was found } - -std::vector > -EndDeviceLorawanMac::Shuffle (std::vector > vector) +std::vector> +EndDeviceLorawanMac::Shuffle(std::vector> vector) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - int size = vector.size (); + int size = vector.size(); - for (int i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) { - uint16_t random = std::floor (m_uniformRV->GetValue (0, size)); - Ptr temp = vector.at (random); - vector.at (random) = vector.at (i); - vector.at (i) = temp; + uint16_t random = std::floor(m_uniformRV->GetValue(0, size)); + Ptr temp = vector.at(random); + vector.at(random) = vector.at(i); + vector.at(i) = temp; } - return vector; + return vector; } ///////////////////////// // Setters and Getters // ///////////////////////// -void EndDeviceLorawanMac::resetRetransmissionParameters () +void +EndDeviceLorawanMac::resetRetransmissionParameters() { - m_retxParams.waitingAck = false; - m_retxParams.retxLeft = m_maxNumbTx; - m_retxParams.packet = 0; - m_retxParams.firstAttempt = Seconds (0); + m_retxParams.waitingAck = false; + m_retxParams.retxLeft = m_maxNumbTx; + m_retxParams.packet = 0; + m_retxParams.firstAttempt = Seconds(0); - // Cancel next retransmissions, if any - Simulator::Cancel (m_nextTx); + // Cancel next retransmissions, if any + Simulator::Cancel(m_nextTx); } void -EndDeviceLorawanMac::SetDataRateAdaptation (bool adapt) +EndDeviceLorawanMac::SetDataRateAdaptation(bool adapt) { - NS_LOG_FUNCTION (this << adapt); - m_enableDRAdapt = adapt; + NS_LOG_FUNCTION(this << adapt); + m_enableDRAdapt = adapt; } bool -EndDeviceLorawanMac::GetDataRateAdaptation (void) +EndDeviceLorawanMac::GetDataRateAdaptation(void) { - return m_enableDRAdapt; + return m_enableDRAdapt; } void -EndDeviceLorawanMac::SetMaxNumberOfTransmissions (uint8_t maxNumbTx) +EndDeviceLorawanMac::SetMaxNumberOfTransmissions(uint8_t maxNumbTx) { - NS_LOG_FUNCTION (this << unsigned(maxNumbTx)); - m_maxNumbTx = maxNumbTx; - m_retxParams.retxLeft = maxNumbTx; + NS_LOG_FUNCTION(this << unsigned(maxNumbTx)); + m_maxNumbTx = maxNumbTx; + m_retxParams.retxLeft = maxNumbTx; } uint8_t -EndDeviceLorawanMac::GetMaxNumberOfTransmissions (void) +EndDeviceLorawanMac::GetMaxNumberOfTransmissions(void) { - NS_LOG_FUNCTION (this ); - return m_maxNumbTx; + NS_LOG_FUNCTION(this); + return m_maxNumbTx; } - void -EndDeviceLorawanMac::SetDataRate (uint8_t dataRate) +EndDeviceLorawanMac::SetDataRate(uint8_t dataRate) { - NS_LOG_FUNCTION (this << unsigned (dataRate)); + NS_LOG_FUNCTION(this << unsigned(dataRate)); - m_dataRate = dataRate; + m_dataRate = dataRate; } uint8_t -EndDeviceLorawanMac::GetDataRate (void) +EndDeviceLorawanMac::GetDataRate(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_dataRate; + return m_dataRate; } void -EndDeviceLorawanMac::SetDeviceAddress (LoraDeviceAddress address) +EndDeviceLorawanMac::SetDeviceAddress(LoraDeviceAddress address) { - NS_LOG_FUNCTION (this << address); + NS_LOG_FUNCTION(this << address); - m_address = address; + m_address = address; } LoraDeviceAddress -EndDeviceLorawanMac::GetDeviceAddress (void) +EndDeviceLorawanMac::GetDeviceAddress(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_address; + return m_address; } void -EndDeviceLorawanMac::OnLinkCheckAns (uint8_t margin, uint8_t gwCnt) +EndDeviceLorawanMac::OnLinkCheckAns(uint8_t margin, uint8_t gwCnt) { - NS_LOG_FUNCTION (this << unsigned(margin) << unsigned(gwCnt)); + NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt)); - m_lastKnownLinkMargin = margin; - m_lastKnownGatewayCount = gwCnt; + m_lastKnownLinkMargin = margin; + m_lastKnownGatewayCount = gwCnt; } void -EndDeviceLorawanMac::OnLinkAdrReq (uint8_t dataRate, uint8_t txPower, - std::list enabledChannels, int repetitions) +EndDeviceLorawanMac::OnLinkAdrReq(uint8_t dataRate, + uint8_t txPower, + std::list enabledChannels, + int repetitions) { - NS_LOG_FUNCTION (this << unsigned (dataRate) << unsigned (txPower) << - repetitions); + NS_LOG_FUNCTION(this << unsigned(dataRate) << unsigned(txPower) << repetitions); - // Three bools for three requirements before setting things up - bool channelMaskOk = true; - bool dataRateOk = true; - bool txPowerOk = true; + // Three bools for three requirements before setting things up + bool channelMaskOk = true; + bool dataRateOk = true; + bool txPowerOk = true; - // Check the channel mask - ///////////////////////// - // Check whether all specified channels exist on this device - auto channelList = m_channelHelper.GetChannelList (); - int channelListSize = channelList.size (); + // Check the channel mask + ///////////////////////// + // Check whether all specified channels exist on this device + auto channelList = m_channelHelper.GetChannelList(); + int channelListSize = channelList.size(); - for (auto it = enabledChannels.begin (); it != enabledChannels.end (); it++) + for (auto it = enabledChannels.begin(); it != enabledChannels.end(); it++) { - if ((*it) > channelListSize) + if ((*it) > channelListSize) { - channelMaskOk = false; - break; + channelMaskOk = false; + break; } } - // Check the dataRate - ///////////////////// - // We need to know we can use it at all - // To assess this, we try and convert it to a SF/BW combination and check if - // those values are valid. Since GetSfFromDataRate and - // GetBandwidthFromDataRate return 0 if the dataRate is not recognized, we - // can check against this. - uint8_t sf = GetSfFromDataRate (dataRate); - double bw = GetBandwidthFromDataRate (dataRate); - NS_LOG_DEBUG ("SF: " << unsigned (sf) << ", BW: " << bw); - if (sf == 0 || bw == 0) + // Check the dataRate + ///////////////////// + // We need to know we can use it at all + // To assess this, we try and convert it to a SF/BW combination and check if + // those values are valid. Since GetSfFromDataRate and + // GetBandwidthFromDataRate return 0 if the dataRate is not recognized, we + // can check against this. + uint8_t sf = GetSfFromDataRate(dataRate); + double bw = GetBandwidthFromDataRate(dataRate); + NS_LOG_DEBUG("SF: " << unsigned(sf) << ", BW: " << bw); + if (sf == 0 || bw == 0) { - dataRateOk = false; - NS_LOG_DEBUG ("Data rate non valid"); + dataRateOk = false; + NS_LOG_DEBUG("Data rate non valid"); } - // We need to know we can use it in at least one of the enabled channels - // Cycle through available channels, stop when at least one is enabled for the - // specified dataRate. - if (dataRateOk && channelMaskOk) // If false, skip the check + // We need to know we can use it in at least one of the enabled channels + // Cycle through available channels, stop when at least one is enabled for the + // specified dataRate. + if (dataRateOk && channelMaskOk) // If false, skip the check { - bool foundAvailableChannel = false; - for (auto it = enabledChannels.begin (); it != enabledChannels.end (); it++) + bool foundAvailableChannel = false; + for (auto it = enabledChannels.begin(); it != enabledChannels.end(); it++) { - NS_LOG_DEBUG ("MinDR: " << unsigned (channelList.at (*it)->GetMinimumDataRate ())); - NS_LOG_DEBUG ("MaxDR: " << unsigned (channelList.at (*it)->GetMaximumDataRate ())); - if (channelList.at (*it)->GetMinimumDataRate () <= dataRate - && channelList.at (*it)->GetMaximumDataRate () >= dataRate) + NS_LOG_DEBUG("MinDR: " << unsigned(channelList.at(*it)->GetMinimumDataRate())); + NS_LOG_DEBUG("MaxDR: " << unsigned(channelList.at(*it)->GetMaximumDataRate())); + if (channelList.at(*it)->GetMinimumDataRate() <= dataRate && + channelList.at(*it)->GetMaximumDataRate() >= dataRate) { - foundAvailableChannel = true; - break; + foundAvailableChannel = true; + break; } } - if (!foundAvailableChannel) + if (!foundAvailableChannel) { - dataRateOk = false; - NS_LOG_DEBUG ("Available channel not found"); + dataRateOk = false; + NS_LOG_DEBUG("Available channel not found"); } } - // Check the txPower - //////////////////// - // Check whether we can use this transmission power - if (GetDbmForTxPower (txPower) == 0) + // Check the txPower + //////////////////// + // Check whether we can use this transmission power + if (GetDbmForTxPower(txPower) == 0) { - txPowerOk = false; + txPowerOk = false; } - NS_LOG_DEBUG ("Finished checking. " << - "ChannelMaskOk: " << channelMaskOk << ", " << - "DataRateOk: " << dataRateOk << ", " << - "txPowerOk: " << txPowerOk); + NS_LOG_DEBUG("Finished checking. " + << "ChannelMaskOk: " << channelMaskOk << ", " + << "DataRateOk: " << dataRateOk << ", " + << "txPowerOk: " << txPowerOk); - // If all checks are successful, set parameters up - ////////////////////////////////////////////////// - if (channelMaskOk && dataRateOk && txPowerOk) + // If all checks are successful, set parameters up + ////////////////////////////////////////////////// + if (channelMaskOk && dataRateOk && txPowerOk) { - // Cycle over all channels in the list - for (uint32_t i = 0; i < m_channelHelper.GetChannelList ().size (); i++) + // Cycle over all channels in the list + for (uint32_t i = 0; i < m_channelHelper.GetChannelList().size(); i++) { - if (std::find (enabledChannels.begin (), enabledChannels.end (), i) != enabledChannels.end ()) + if (std::find(enabledChannels.begin(), enabledChannels.end(), i) != + enabledChannels.end()) { - m_channelHelper.GetChannelList ().at (i)->SetEnabledForUplink (); - NS_LOG_DEBUG ("Channel " << i << " enabled"); + m_channelHelper.GetChannelList().at(i)->SetEnabledForUplink(); + NS_LOG_DEBUG("Channel " << i << " enabled"); } - else + else { - m_channelHelper.GetChannelList ().at (i)->DisableForUplink (); - NS_LOG_DEBUG ("Channel " << i << " disabled"); + m_channelHelper.GetChannelList().at(i)->DisableForUplink(); + NS_LOG_DEBUG("Channel " << i << " disabled"); } } - // Set the data rate - m_dataRate = dataRate; + // Set the data rate + m_dataRate = dataRate; - // Set the transmission power - m_txPower = GetDbmForTxPower (txPower); + // Set the transmission power + m_txPower = GetDbmForTxPower(txPower); } - // Craft a LinkAdrAns MAC command as a response - /////////////////////////////////////////////// - m_macCommandList.push_back (CreateObject (txPowerOk, dataRateOk, - channelMaskOk)); + // Craft a LinkAdrAns MAC command as a response + /////////////////////////////////////////////// + m_macCommandList.push_back(CreateObject(txPowerOk, dataRateOk, channelMaskOk)); } void -EndDeviceLorawanMac::OnDutyCycleReq (double dutyCycle) +EndDeviceLorawanMac::OnDutyCycleReq(double dutyCycle) { - NS_LOG_FUNCTION (this << dutyCycle); + NS_LOG_FUNCTION(this << dutyCycle); - // Make sure we get a value that makes sense - NS_ASSERT (0 <= dutyCycle && dutyCycle < 1); + // Make sure we get a value that makes sense + NS_ASSERT(0 <= dutyCycle && dutyCycle < 1); - // Set the new duty cycle value - m_aggregatedDutyCycle = dutyCycle; + // Set the new duty cycle value + m_aggregatedDutyCycle = dutyCycle; - // Craft a DutyCycleAns as response - NS_LOG_INFO ("Adding DutyCycleAns reply"); - m_macCommandList.push_back (CreateObject ()); + // Craft a DutyCycleAns as response + NS_LOG_INFO("Adding DutyCycleAns reply"); + m_macCommandList.push_back(CreateObject()); } void -EndDeviceLorawanMac::OnRxClassParamSetupReq (Ptr rxParamSetupReq) -{ } +EndDeviceLorawanMac::OnRxClassParamSetupReq(Ptr rxParamSetupReq) +{ +} void -EndDeviceLorawanMac::OnRxParamSetupReq (Ptr rxParamSetupReq) +EndDeviceLorawanMac::OnRxParamSetupReq(Ptr rxParamSetupReq) { - NS_LOG_FUNCTION (this << rxParamSetupReq); + NS_LOG_FUNCTION(this << rxParamSetupReq); - // static_cast(this)->OnRxClassParamSetupReq (rxParamSetupReq); - OnRxClassParamSetupReq (rxParamSetupReq); + // static_cast(this)->OnRxClassParamSetupReq (rxParamSetupReq); + OnRxClassParamSetupReq(rxParamSetupReq); } void -EndDeviceLorawanMac::OnDevStatusReq (void) +EndDeviceLorawanMac::OnDevStatusReq(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - uint8_t battery = 10; // XXX Fake battery level - uint8_t margin = 10; // XXX Fake margin + uint8_t battery = 10; // XXX Fake battery level + uint8_t margin = 10; // XXX Fake margin - // Craft a RxParamSetupAns as response - NS_LOG_INFO ("Adding DevStatusAns reply"); - m_macCommandList.push_back (CreateObject (battery, margin)); + // Craft a RxParamSetupAns as response + NS_LOG_INFO("Adding DevStatusAns reply"); + m_macCommandList.push_back(CreateObject(battery, margin)); } void -EndDeviceLorawanMac::OnNewChannelReq (uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate) +EndDeviceLorawanMac::OnNewChannelReq(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate) { - NS_LOG_FUNCTION (this); - + NS_LOG_FUNCTION(this); - bool dataRateRangeOk = true; // XXX Check whether the new data rate range is ok - bool channelFrequencyOk = true; // XXX Check whether the frequency is ok + bool dataRateRangeOk = true; // XXX Check whether the new data rate range is ok + bool channelFrequencyOk = true; // XXX Check whether the frequency is ok - // TODO Return false if one of the checks above failed - // TODO Create new channel in the LogicalLoraChannelHelper + // TODO Return false if one of the checks above failed + // TODO Create new channel in the LogicalLoraChannelHelper - SetLogicalChannel (chIndex, frequency, minDataRate, maxDataRate); + SetLogicalChannel(chIndex, frequency, minDataRate, maxDataRate); - NS_LOG_INFO ("Adding NewChannelAns reply"); - m_macCommandList.push_back (CreateObject (dataRateRangeOk, - channelFrequencyOk)); + NS_LOG_INFO("Adding NewChannelAns reply"); + m_macCommandList.push_back(CreateObject(dataRateRangeOk, channelFrequencyOk)); } void -EndDeviceLorawanMac::AddLogicalChannel (double frequency) +EndDeviceLorawanMac::AddLogicalChannel(double frequency) { - NS_LOG_FUNCTION (this << frequency); + NS_LOG_FUNCTION(this << frequency); - m_channelHelper.AddChannel (frequency); + m_channelHelper.AddChannel(frequency); } void -EndDeviceLorawanMac::AddLogicalChannel (Ptr logicalChannel) +EndDeviceLorawanMac::AddLogicalChannel(Ptr logicalChannel) { - NS_LOG_FUNCTION (this << logicalChannel); + NS_LOG_FUNCTION(this << logicalChannel); - m_channelHelper.AddChannel (logicalChannel); + m_channelHelper.AddChannel(logicalChannel); } void -EndDeviceLorawanMac::SetLogicalChannel (uint8_t chIndex, double frequency, - uint8_t minDataRate, uint8_t maxDataRate) +EndDeviceLorawanMac::SetLogicalChannel(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate) { - NS_LOG_FUNCTION (this << unsigned (chIndex) << frequency << - unsigned (minDataRate) << unsigned(maxDataRate)); + NS_LOG_FUNCTION(this << unsigned(chIndex) << frequency << unsigned(minDataRate) + << unsigned(maxDataRate)); - m_channelHelper.SetChannel (chIndex, CreateObject - (frequency, minDataRate, maxDataRate)); + m_channelHelper.SetChannel( + chIndex, + CreateObject(frequency, minDataRate, maxDataRate)); } void -EndDeviceLorawanMac::AddSubBand (double startFrequency, double endFrequency, double dutyCycle, double maxTxPowerDbm) +EndDeviceLorawanMac::AddSubBand(double startFrequency, + double endFrequency, + double dutyCycle, + double maxTxPowerDbm) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_channelHelper.AddSubBand (startFrequency, endFrequency, dutyCycle, maxTxPowerDbm); + m_channelHelper.AddSubBand(startFrequency, endFrequency, dutyCycle, maxTxPowerDbm); } double -EndDeviceLorawanMac::GetAggregatedDutyCycle (void) +EndDeviceLorawanMac::GetAggregatedDutyCycle(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_aggregatedDutyCycle; + return m_aggregatedDutyCycle; } void -EndDeviceLorawanMac::AddMacCommand (Ptr macCommand) +EndDeviceLorawanMac::AddMacCommand(Ptr macCommand) { - NS_LOG_FUNCTION (this << macCommand); + NS_LOG_FUNCTION(this << macCommand); - m_macCommandList.push_back (macCommand); + m_macCommandList.push_back(macCommand); } uint8_t -EndDeviceLorawanMac::GetTransmissionPower (void) +EndDeviceLorawanMac::GetTransmissionPower(void) { - return m_txPower; -} -} + return m_txPower; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/end-device-lorawan-mac.h b/model/end-device-lorawan-mac.h index a013a6a1a4..e2eac646bc 100644 --- a/model/end-device-lorawan-mac.h +++ b/model/end-device-lorawan-mac.h @@ -24,478 +24,491 @@ #ifndef END_DEVICE_LORAWAN_MAC_H #define END_DEVICE_LORAWAN_MAC_H -#include "ns3/lorawan-mac.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/lora-frame-header.h" +#include "lora-device-address.h" +#include "lora-frame-header.h" +#include "lorawan-mac-header.h" +#include "lorawan-mac.h" + #include "ns3/random-variable-stream.h" -#include "ns3/lora-device-address.h" #include "ns3/traced-value.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Class representing the MAC layer of a LoRaWAN device. */ class EndDeviceLorawanMac : public LorawanMac { -public: - static TypeId GetTypeId (void); - - EndDeviceLorawanMac (); - virtual ~EndDeviceLorawanMac (); - - ///////////////////// - // Sending methods // - ///////////////////// - - /** - * Send a packet. - * - * The MAC layer of the ED will take care of using the right parameters. - * - * \param packet the packet to send - */ - virtual void Send (Ptr packet); - - /** - * Checking if we are performing the transmission of a new packet or a retransmission, and call SendToPhy function. - * - * \param packet the packet to send - */ - virtual void DoSend (Ptr packet); - - /** - * Add headers and send a packet with the sending function of the physical layer. - * - * \param packet the packet to send - */ - virtual void SendToPhy (Ptr packet); - - /** - * Postpone transmission to the specified time and delete previously scheduled transmissions if present. - * - * \param nextTxDelay Delay at which the transmission will be performed. - */ - virtual void postponeTransmission (Time nextTxDelay, Ptr); - - - /////////////////////// - // Receiving methods // - /////////////////////// - - /** - * Receive a packet. - * - * This method is typically registered as a callback in the underlying PHY - * layer so that it's called when a packet is going up the stack. - * - * \param packet the received packet. - */ - virtual void Receive (Ptr packet); - - virtual void FailedReception (Ptr packet); - - /** - * Perform the actions that are required after a packet send. - * - * This function handles opening of the first receive window. - */ - virtual void TxFinished (Ptr packet); - - ///////////////////////// - // Getters and Setters // - ///////////////////////// - - /** - * Reset retransmission parameters contained in the structure LoraRetxParams - */ - virtual void resetRetransmissionParameters (); - - /** - * Enable data rate adaptation in the retransmitting procedure. - * - * \param adapt If the data rate adaptation is enabled or not. - */ - void SetDataRateAdaptation (bool adapt); - - /** - * Get if data rate adaptation is enabled or not. - */ - bool GetDataRateAdaptation (void); - - /** - * Set the maximum number of transmissions allowed. - * - * \param maxNumbTx The maximum number of transmissions allowed - */ - void SetMaxNumberOfTransmissions (uint8_t maxNumbTx); - - /** - * Set the maximum number of transmissions allowed. - */ - uint8_t GetMaxNumberOfTransmissions (void); - - /** - * Set the data rate this end device will use when transmitting. For End - * Devices, this value is assumed to be fixed, and can be modified via MAC - * commands issued by the GW. - * - * \param dataRate The dataRate to use when transmitting. - */ - void SetDataRate (uint8_t dataRate); - - /** - * Get the data rate this end device is set to use. - * - * \return The data rate this device uses when transmitting. - */ - uint8_t GetDataRate (void); - - /** - * Get the transmission power this end device is set to use. - * - * \return The transmission power this device uses when transmitting. - */ - virtual uint8_t GetTransmissionPower (void); - - /** - * Set the network address of this device. - * - * \param address The address to set. - */ - void SetDeviceAddress (LoraDeviceAddress address); - - /** - * Get the network address of this device. - * - * \return This device's address. - */ - LoraDeviceAddress GetDeviceAddress (void); - - /** - * Set a value for the RX1DROffset parameter. - * - * This value decides the offset to use when deciding the DataRate of the - * downlink transmission during the first receive window from the - * replyDataRateMatrix. - * - * \param rx1DrOffset The value to set for the offset. - */ - // void SetRx1DrOffset (uint8_t rx1DrOffset); - - /** - * Get the value of the RX1DROffset parameter. - * - * \return The value of the RX1DROffset parameter. - */ - // uint8_t GetRx1DrOffset (void); - - /** - * Get the aggregated duty cycle. - * - * \return A time instance containing the aggregated duty cycle in fractional - * form. - */ - double GetAggregatedDutyCycle (void); - - ///////////////////////// - // MAC command methods // - ///////////////////////// - - /** - * Add the necessary options and MAC commands to the LoraFrameHeader. - * - * \param frameHeader The frame header on which to apply the options. - */ - void ApplyNecessaryOptions (LoraFrameHeader &frameHeader); - - /** - * Add the necessary options and MAC commands to the LorawanMacHeader. - * - * \param macHeader The mac header on which to apply the options. - */ - void ApplyNecessaryOptions (LorawanMacHeader &macHeader); - - /** - * Set the message type to send when the Send method is called. - */ - void SetMType (LorawanMacHeader::MType mType); - - /** - * Get the message type to send when the Send method is called. - */ - LorawanMacHeader::MType GetMType (void); - - /** - * Parse and take action on the commands contained on this FrameHeader. - */ - void ParseCommands (LoraFrameHeader frameHeader); - - /** - * Perform the actions that need to be taken when receiving a LinkCheckAns command. - * - * \param margin The margin value of the command. - * \param gwCnt The gateway count value of the command. - */ - void OnLinkCheckAns (uint8_t margin, uint8_t gwCnt); - - /** - * Perform the actions that need to be taken when receiving a LinkAdrReq command. - * - * \param dataRate The data rate value of the command. - * \param txPower The transmission power value of the command. - * \param enabledChannels A list of the enabled channels. - * \param repetitions The number of repetitions prescribed by the command. - */ - void OnLinkAdrReq (uint8_t dataRate, uint8_t txPower, - std::list enabledChannels, int repetitions); - - /** - * Perform the actions that need to be taken when receiving a DutyCycleReq command. - * - * \param dutyCycle The aggregate duty cycle prescribed by the command, in - * fraction form. - */ - void OnDutyCycleReq (double dutyCycle); - - /** - * Perform the actions that need to be taken when receiving a RxParamSetupReq command. - * - * \param rxParamSetupReq The Parameter Setup Request - */ - void OnRxParamSetupReq (Ptr rxParamSetupReq); - - /** - * Perform the actions that need to be taken when receiving a RxParamSetupReq - * command based on the Device's Class Type. - * - * \param rxParamSetupReq The Parameter Setup Request - */ - virtual void OnRxClassParamSetupReq (Ptr rxParamSetupReq); - - /** - * Perform the actions that need to be taken when receiving a DevStatusReq command. - */ - void OnDevStatusReq (void); - - /** - * Perform the actions that need to be taken when receiving a NewChannelReq command. - */ - void OnNewChannelReq (uint8_t chIndex, double frequency, uint8_t minDataRate, - uint8_t maxDataRate); - - //////////////////////////////////// - // Logical channel administration // - //////////////////////////////////// - - /** - * Add a logical channel to the helper. - * - * \param frequency The channel's center frequency. - */ - void AddLogicalChannel (double frequency); - - /** - * Set a new logical channel in the helper. - * - * \param chIndex The channel's new index. - * \param frequency The channel's center frequency. - * \param minDataRate The minimum data rate allowed on the channel. - * \param maxDataRate The maximum data rate allowed on the channel. - */ - void SetLogicalChannel (uint8_t chIndex, double frequency, - uint8_t minDataRate, uint8_t maxDataRate); - - /** - * Add a logical channel to the helper. - * - * \param frequency The channel's center frequency. - */ - void AddLogicalChannel (Ptr logicalChannel); - - /** - * Add a subband to the logical channel helper. - * - * \param startFrequency The SubBand's lowest frequency. - * \param endFrequency The SubBand's highest frequency. - * \param dutyCycle The SubBand's duty cycle, in fraction form. - * \param maxTxPowerDbm The maximum transmission power allowed on the SubBand. - */ - void AddSubBand (double startFrequency, double endFrequency, double dutyCycle, - double maxTxPowerDbm); - - /** - * Add a MAC command to the list of those that will be sent out in the next - * packet. - */ - void AddMacCommand (Ptr macCommand); - -protected: - /** - * Structure representing the parameters that will be used in the - * retransmission procedure. - */ - struct LoraRetxParameters - { - Time firstAttempt; - Ptr packet = 0; - bool waitingAck = false; - uint8_t retxLeft; - }; - - /** - * Enable Data Rate adaptation during the retransmission procedure. - */ - bool m_enableDRAdapt; - - /** - * Maximum number of transmission allowed. - */ - uint8_t m_maxNumbTx; - - /** - * The DataRate this device is using to transmit. - */ - TracedValue m_dataRate; - - /** - * The transmission power this device is using to transmit. - */ - TracedValue m_txPower; - - /** - * The coding rate used by this device. - */ - uint8_t m_codingRate; - - /** - * Whether or not the header is disabled for communications by this device. - */ - bool m_headerDisabled; - - /** - * The address of this device. - */ - LoraDeviceAddress m_address; - - /** - * Find the minimum waiting time before the next possible transmission based - * on End Device's Class Type. - */ - virtual Time GetNextClassTransmissionDelay (Time waitingTime); - - /** - * Find a suitable channel for transmission. The channel is chosen among the - * ones that are available in the ED's LogicalLoraChannel, based on their duty - * cycle limitations. - */ - Ptr GetChannelForTx (void); - - /** - * The duration of a receive window in number of symbols. This should be - * converted to time based or the reception parameter used. - * - * The downlink preamble transmitted by the gateways contains 8 symbols. - * The receiver requires 5 symbols to detect the preamble and synchronize. - * Therefore there must be a 5 symbols overlap between the receive window - * and the transmitted preamble. - * (Ref: Recommended SX1272/76 Settings for EU868 LoRaWAN Network Operation ) - */ - uint8_t m_receiveWindowDurationInSymbols; - - /** - * List of the MAC commands that need to be applied to the next UL packet. - */ - std::list > m_macCommandList; - - /* Structure containing the retransmission parameters - * for this device. - */ - struct LoraRetxParameters m_retxParams; - - /** - * An uniform random variable, used by the Shuffle method to randomly reorder - * the channel list. - */ - Ptr m_uniformRV; - - ///////////////// - // Callbacks // - ///////////////// - - /** - * The trace source fired when the transmission procedure is finished. - * - * \see class CallBackTraceSource - */ - TracedCallback > m_requiredTxCallback; - -private: - /** - * Randomly shuffle a Ptr vector. - * - * Used to pick a random channel on which to send the packet. - */ - std::vector > Shuffle (std::vector > vector); - - /** - * Find the minimum waiting time before the next possible transmission. - */ - Time GetNextTransmissionDelay (void); - - /** - * Whether this device's data rate should be controlled by the NS. - */ - bool m_controlDataRate; - - /** - * The event of retransmitting a packet in a consecutive moment if an ACK is not received. - * - * This Event is used to cancel the retransmission if the ACK is found in ParseCommand function and - * if a newer packet is delivered from the application to be sent. - */ - EventId m_nextTx; - - /** - * The event of transmitting a packet in a consecutive moment, when the duty cycle let us transmit. - * - * This Event is used to cancel the transmission of this packet if a newer packet is delivered from the application to be sent. - */ - EventId m_nextRetx; - - /** - * The last known link margin. - * - * This value is obtained (and updated) when a LinkCheckAns Mac command is - * received. - */ - TracedValue m_lastKnownLinkMargin; - - /** - * The last known gateway count (i.e., gateways that are in communication - * range with this end device) - * - * This value is obtained (and updated) when a LinkCheckAns Mac command is - * received. - */ - TracedValue m_lastKnownGatewayCount; - - /** - * The aggregated duty cycle this device needs to respect across all sub-bands. - */ - TracedValue m_aggregatedDutyCycle; - - /** - * The message type to apply to packets sent with the Send method. - */ - LorawanMacHeader::MType m_mType; - - uint16_t m_currentFCnt; + public: + static TypeId GetTypeId(void); + + EndDeviceLorawanMac(); + virtual ~EndDeviceLorawanMac(); + + ///////////////////// + // Sending methods // + ///////////////////// + + /** + * Send a packet. + * + * The MAC layer of the ED will take care of using the right parameters. + * + * \param packet the packet to send + */ + virtual void Send(Ptr packet); + + /** + * Checking if we are performing the transmission of a new packet or a retransmission, and call + * SendToPhy function. + * + * \param packet the packet to send + */ + virtual void DoSend(Ptr packet); + + /** + * Add headers and send a packet with the sending function of the physical layer. + * + * \param packet the packet to send + */ + virtual void SendToPhy(Ptr packet); + + /** + * Postpone transmission to the specified time and delete previously scheduled transmissions if + * present. + * + * \param nextTxDelay Delay at which the transmission will be performed. + */ + virtual void postponeTransmission(Time nextTxDelay, Ptr); + + /////////////////////// + // Receiving methods // + /////////////////////// + + /** + * Receive a packet. + * + * This method is typically registered as a callback in the underlying PHY + * layer so that it's called when a packet is going up the stack. + * + * \param packet the received packet. + */ + virtual void Receive(Ptr packet); + + virtual void FailedReception(Ptr packet); + + /** + * Perform the actions that are required after a packet send. + * + * This function handles opening of the first receive window. + */ + virtual void TxFinished(Ptr packet); + + ///////////////////////// + // Getters and Setters // + ///////////////////////// + + /** + * Reset retransmission parameters contained in the structure LoraRetxParams + */ + virtual void resetRetransmissionParameters(); + + /** + * Enable data rate adaptation in the retransmitting procedure. + * + * \param adapt If the data rate adaptation is enabled or not. + */ + void SetDataRateAdaptation(bool adapt); + + /** + * Get if data rate adaptation is enabled or not. + */ + bool GetDataRateAdaptation(void); + + /** + * Set the maximum number of transmissions allowed. + * + * \param maxNumbTx The maximum number of transmissions allowed + */ + void SetMaxNumberOfTransmissions(uint8_t maxNumbTx); + + /** + * Set the maximum number of transmissions allowed. + */ + uint8_t GetMaxNumberOfTransmissions(void); + + /** + * Set the data rate this end device will use when transmitting. For End + * Devices, this value is assumed to be fixed, and can be modified via MAC + * commands issued by the GW. + * + * \param dataRate The dataRate to use when transmitting. + */ + void SetDataRate(uint8_t dataRate); + + /** + * Get the data rate this end device is set to use. + * + * \return The data rate this device uses when transmitting. + */ + uint8_t GetDataRate(void); + + /** + * Get the transmission power this end device is set to use. + * + * \return The transmission power this device uses when transmitting. + */ + virtual uint8_t GetTransmissionPower(void); + + /** + * Set the network address of this device. + * + * \param address The address to set. + */ + void SetDeviceAddress(LoraDeviceAddress address); + + /** + * Get the network address of this device. + * + * \return This device's address. + */ + LoraDeviceAddress GetDeviceAddress(void); + + /** + * Set a value for the RX1DROffset parameter. + * + * This value decides the offset to use when deciding the DataRate of the + * downlink transmission during the first receive window from the + * replyDataRateMatrix. + * + * \param rx1DrOffset The value to set for the offset. + */ + // void SetRx1DrOffset (uint8_t rx1DrOffset); + + /** + * Get the value of the RX1DROffset parameter. + * + * \return The value of the RX1DROffset parameter. + */ + // uint8_t GetRx1DrOffset (void); + + /** + * Get the aggregated duty cycle. + * + * \return A time instance containing the aggregated duty cycle in fractional + * form. + */ + double GetAggregatedDutyCycle(void); + + ///////////////////////// + // MAC command methods // + ///////////////////////// + + /** + * Add the necessary options and MAC commands to the LoraFrameHeader. + * + * \param frameHeader The frame header on which to apply the options. + */ + void ApplyNecessaryOptions(LoraFrameHeader& frameHeader); + + /** + * Add the necessary options and MAC commands to the LorawanMacHeader. + * + * \param macHeader The mac header on which to apply the options. + */ + void ApplyNecessaryOptions(LorawanMacHeader& macHeader); + + /** + * Set the message type to send when the Send method is called. + */ + void SetMType(LorawanMacHeader::MType mType); + + /** + * Get the message type to send when the Send method is called. + */ + LorawanMacHeader::MType GetMType(void); + + /** + * Parse and take action on the commands contained on this FrameHeader. + */ + void ParseCommands(LoraFrameHeader frameHeader); + + /** + * Perform the actions that need to be taken when receiving a LinkCheckAns command. + * + * \param margin The margin value of the command. + * \param gwCnt The gateway count value of the command. + */ + void OnLinkCheckAns(uint8_t margin, uint8_t gwCnt); + + /** + * Perform the actions that need to be taken when receiving a LinkAdrReq command. + * + * \param dataRate The data rate value of the command. + * \param txPower The transmission power value of the command. + * \param enabledChannels A list of the enabled channels. + * \param repetitions The number of repetitions prescribed by the command. + */ + void OnLinkAdrReq(uint8_t dataRate, + uint8_t txPower, + std::list enabledChannels, + int repetitions); + + /** + * Perform the actions that need to be taken when receiving a DutyCycleReq command. + * + * \param dutyCycle The aggregate duty cycle prescribed by the command, in + * fraction form. + */ + void OnDutyCycleReq(double dutyCycle); + + /** + * Perform the actions that need to be taken when receiving a RxParamSetupReq command. + * + * \param rxParamSetupReq The Parameter Setup Request + */ + void OnRxParamSetupReq(Ptr rxParamSetupReq); + + /** + * Perform the actions that need to be taken when receiving a RxParamSetupReq + * command based on the Device's Class Type. + * + * \param rxParamSetupReq The Parameter Setup Request + */ + virtual void OnRxClassParamSetupReq(Ptr rxParamSetupReq); + + /** + * Perform the actions that need to be taken when receiving a DevStatusReq command. + */ + void OnDevStatusReq(void); + + /** + * Perform the actions that need to be taken when receiving a NewChannelReq command. + */ + void OnNewChannelReq(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate); + + //////////////////////////////////// + // Logical channel administration // + //////////////////////////////////// + + /** + * Add a logical channel to the helper. + * + * \param frequency The channel's center frequency. + */ + void AddLogicalChannel(double frequency); + + /** + * Set a new logical channel in the helper. + * + * \param chIndex The channel's new index. + * \param frequency The channel's center frequency. + * \param minDataRate The minimum data rate allowed on the channel. + * \param maxDataRate The maximum data rate allowed on the channel. + */ + void SetLogicalChannel(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate); + + /** + * Add a logical channel to the helper. + * + * \param frequency The channel's center frequency. + */ + void AddLogicalChannel(Ptr logicalChannel); + + /** + * Add a subband to the logical channel helper. + * + * \param startFrequency The SubBand's lowest frequency. + * \param endFrequency The SubBand's highest frequency. + * \param dutyCycle The SubBand's duty cycle, in fraction form. + * \param maxTxPowerDbm The maximum transmission power allowed on the SubBand. + */ + void AddSubBand(double startFrequency, + double endFrequency, + double dutyCycle, + double maxTxPowerDbm); + + /** + * Add a MAC command to the list of those that will be sent out in the next + * packet. + */ + void AddMacCommand(Ptr macCommand); + + protected: + /** + * Structure representing the parameters that will be used in the + * retransmission procedure. + */ + struct LoraRetxParameters + { + Time firstAttempt; + Ptr packet = 0; + bool waitingAck = false; + uint8_t retxLeft; + }; + + /** + * Enable Data Rate adaptation during the retransmission procedure. + */ + bool m_enableDRAdapt; + + /** + * Maximum number of transmission allowed. + */ + uint8_t m_maxNumbTx; + + /** + * The DataRate this device is using to transmit. + */ + TracedValue m_dataRate; + + /** + * The transmission power this device is using to transmit. + */ + TracedValue m_txPower; + + /** + * The coding rate used by this device. + */ + uint8_t m_codingRate; + + /** + * Whether or not the header is disabled for communications by this device. + */ + bool m_headerDisabled; + + /** + * The address of this device. + */ + LoraDeviceAddress m_address; + + /** + * Find the minimum waiting time before the next possible transmission based + * on End Device's Class Type. + */ + virtual Time GetNextClassTransmissionDelay(Time waitingTime); + + /** + * Find a suitable channel for transmission. The channel is chosen among the + * ones that are available in the ED's LogicalLoraChannel, based on their duty + * cycle limitations. + */ + Ptr GetChannelForTx(void); + + /** + * The duration of a receive window in number of symbols. This should be + * converted to time based or the reception parameter used. + * + * The downlink preamble transmitted by the gateways contains 8 symbols. + * The receiver requires 5 symbols to detect the preamble and synchronize. + * Therefore there must be a 5 symbols overlap between the receive window + * and the transmitted preamble. + * (Ref: Recommended SX1272/76 Settings for EU868 LoRaWAN Network Operation ) + */ + uint8_t m_receiveWindowDurationInSymbols; + + /** + * List of the MAC commands that need to be applied to the next UL packet. + */ + std::list> m_macCommandList; + + /* Structure containing the retransmission parameters + * for this device. + */ + struct LoraRetxParameters m_retxParams; + + /** + * An uniform random variable, used by the Shuffle method to randomly reorder + * the channel list. + */ + Ptr m_uniformRV; + + ///////////////// + // Callbacks // + ///////////////// + + /** + * The trace source fired when the transmission procedure is finished. + * + * \see class CallBackTraceSource + */ + TracedCallback> m_requiredTxCallback; + + private: + /** + * Randomly shuffle a Ptr vector. + * + * Used to pick a random channel on which to send the packet. + */ + std::vector> Shuffle(std::vector> vector); + + /** + * Find the minimum waiting time before the next possible transmission. + */ + Time GetNextTransmissionDelay(void); + + /** + * Whether this device's data rate should be controlled by the NS. + */ + bool m_controlDataRate; + + /** + * The event of retransmitting a packet in a consecutive moment if an ACK is not received. + * + * This Event is used to cancel the retransmission if the ACK is found in ParseCommand function + * and if a newer packet is delivered from the application to be sent. + */ + EventId m_nextTx; + + /** + * The event of transmitting a packet in a consecutive moment, when the duty cycle let us + * transmit. + * + * This Event is used to cancel the transmission of this packet if a newer packet is delivered + * from the application to be sent. + */ + EventId m_nextRetx; + + /** + * The last known link margin. + * + * This value is obtained (and updated) when a LinkCheckAns Mac command is + * received. + */ + TracedValue m_lastKnownLinkMargin; + + /** + * The last known gateway count (i.e., gateways that are in communication + * range with this end device) + * + * This value is obtained (and updated) when a LinkCheckAns Mac command is + * received. + */ + TracedValue m_lastKnownGatewayCount; + + /** + * The aggregated duty cycle this device needs to respect across all sub-bands. + */ + TracedValue m_aggregatedDutyCycle; + + /** + * The message type to apply to packets sent with the Send method. + */ + LorawanMacHeader::MType m_mType; + + uint16_t m_currentFCnt; }; +} // namespace lorawan -} /* namespace ns3 */ - -} +} // namespace ns3 #endif /* END_DEVICE_LORAWAN_MAC_H */ diff --git a/model/end-device-status.cc b/model/end-device-status.cc index 2891e0ba5b..bd52a97f9c 100644 --- a/model/end-device-status.cc +++ b/model/end-device-status.cc @@ -19,56 +19,59 @@ * Davide Magrin */ -#include "ns3/end-device-status.h" -#include "ns3/simulator.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/lora-frame-header.h" +#include "end-device-status.h" + +#include "lora-frame-header.h" +#include "lora-tag.h" +#include "lorawan-mac-header.h" + +#include "ns3/command-line.h" #include "ns3/log.h" +#include "ns3/packet.h" #include "ns3/pointer.h" -#include "ns3/command-line.h" #include "ns3/simulator.h" -#include "ns3/packet.h" -#include "ns3/lora-tag.h" #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("EndDeviceStatus"); +NS_LOG_COMPONENT_DEFINE("EndDeviceStatus"); TypeId -EndDeviceStatus::GetTypeId (void) +EndDeviceStatus::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::EndDeviceStatus") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::EndDeviceStatus") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -EndDeviceStatus::EndDeviceStatus (LoraDeviceAddress endDeviceAddress, - Ptr endDeviceMac) - : m_reply (EndDeviceStatus::Reply ()), - m_endDeviceAddress (endDeviceAddress), - m_receivedPacketList (ReceivedPacketList ()), - m_mac (endDeviceMac) +EndDeviceStatus::EndDeviceStatus(LoraDeviceAddress endDeviceAddress, + Ptr endDeviceMac) + : m_reply(EndDeviceStatus::Reply()), + m_endDeviceAddress(endDeviceAddress), + m_receivedPacketList(ReceivedPacketList()), + m_mac(endDeviceMac) { - NS_LOG_FUNCTION (endDeviceAddress); + NS_LOG_FUNCTION(endDeviceAddress); } -EndDeviceStatus::EndDeviceStatus () +EndDeviceStatus::EndDeviceStatus() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Initialize data structure - m_reply = EndDeviceStatus::Reply (); - m_receivedPacketList = ReceivedPacketList (); + // Initialize data structure + m_reply = EndDeviceStatus::Reply(); + m_receivedPacketList = ReceivedPacketList(); } -EndDeviceStatus::~EndDeviceStatus () +EndDeviceStatus::~EndDeviceStatus() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } /////////////// @@ -76,162 +79,162 @@ EndDeviceStatus::~EndDeviceStatus () /////////////// uint8_t -EndDeviceStatus::GetFirstReceiveWindowSpreadingFactor () +EndDeviceStatus::GetFirstReceiveWindowSpreadingFactor() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_firstReceiveWindowSpreadingFactor; + return m_firstReceiveWindowSpreadingFactor; } double -EndDeviceStatus::GetFirstReceiveWindowFrequency () +EndDeviceStatus::GetFirstReceiveWindowFrequency() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_firstReceiveWindowFrequency; + return m_firstReceiveWindowFrequency; } uint8_t -EndDeviceStatus::GetSecondReceiveWindowOffset () +EndDeviceStatus::GetSecondReceiveWindowOffset() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_secondReceiveWindowOffset; + return m_secondReceiveWindowOffset; } double -EndDeviceStatus::GetSecondReceiveWindowFrequency () +EndDeviceStatus::GetSecondReceiveWindowFrequency() { - NS_LOG_FUNCTION_NOARGS (); - return m_secondReceiveWindowFrequency; + NS_LOG_FUNCTION_NOARGS(); + return m_secondReceiveWindowFrequency; } Ptr -EndDeviceStatus::GetCompleteReplyPacket (void) +EndDeviceStatus::GetCompleteReplyPacket(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Start from reply payload - Ptr replyPacket; - if (m_reply.payload) // If it has APP data to send + // Start from reply payload + Ptr replyPacket; + if (m_reply.payload) // If it has APP data to send { - NS_LOG_DEBUG ("Crafting reply packet from existing payload"); - replyPacket = m_reply.payload->Copy (); + NS_LOG_DEBUG("Crafting reply packet from existing payload"); + replyPacket = m_reply.payload->Copy(); } - else // If no APP data needs to be sent, use an empty payload + else // If no APP data needs to be sent, use an empty payload { - NS_LOG_DEBUG ("Crafting reply packet using an empty payload"); - replyPacket = Create (0); + NS_LOG_DEBUG("Crafting reply packet using an empty payload"); + replyPacket = Create(0); } - // Add headers - m_reply.frameHeader.SetAddress (m_endDeviceAddress); - Ptr lastPacket = GetLastPacketReceivedFromDevice ()->Copy (); - LorawanMacHeader mHdr; - LoraFrameHeader fHdr; - fHdr.SetAsUplink (); - lastPacket->RemoveHeader (mHdr); - lastPacket->RemoveHeader (fHdr); - m_reply.frameHeader.SetFCnt (fHdr.GetFCnt ()); - m_reply.macHeader.SetMType (LorawanMacHeader::UNCONFIRMED_DATA_DOWN); - replyPacket->AddHeader (m_reply.frameHeader); - replyPacket->AddHeader (m_reply.macHeader); + // Add headers + m_reply.frameHeader.SetAddress(m_endDeviceAddress); + Ptr lastPacket = GetLastPacketReceivedFromDevice()->Copy(); + LorawanMacHeader mHdr; + LoraFrameHeader fHdr; + fHdr.SetAsUplink(); + lastPacket->RemoveHeader(mHdr); + lastPacket->RemoveHeader(fHdr); + m_reply.frameHeader.SetFCnt(fHdr.GetFCnt()); + m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN); + replyPacket->AddHeader(m_reply.frameHeader); + replyPacket->AddHeader(m_reply.macHeader); - NS_LOG_DEBUG ("Added MAC header" << m_reply.macHeader); - NS_LOG_DEBUG ("Added frame header" << m_reply.frameHeader); + NS_LOG_DEBUG("Added MAC header" << m_reply.macHeader); + NS_LOG_DEBUG("Added frame header" << m_reply.frameHeader); - return replyPacket; + return replyPacket; } bool -EndDeviceStatus::NeedsReply (void) +EndDeviceStatus::NeedsReply(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_reply.needsReply; + return m_reply.needsReply; } LorawanMacHeader -EndDeviceStatus::GetReplyMacHeader () +EndDeviceStatus::GetReplyMacHeader() { - NS_LOG_FUNCTION_NOARGS (); - return m_reply.macHeader; + NS_LOG_FUNCTION_NOARGS(); + return m_reply.macHeader; } LoraFrameHeader -EndDeviceStatus::GetReplyFrameHeader () +EndDeviceStatus::GetReplyFrameHeader() { - NS_LOG_FUNCTION_NOARGS (); - return m_reply.frameHeader; + NS_LOG_FUNCTION_NOARGS(); + return m_reply.frameHeader; } Ptr -EndDeviceStatus::GetReplyPayload (void) +EndDeviceStatus::GetReplyPayload(void) { - NS_LOG_FUNCTION_NOARGS (); - return m_reply.payload->Copy (); + NS_LOG_FUNCTION_NOARGS(); + return m_reply.payload->Copy(); } Ptr -EndDeviceStatus::GetMac (void) +EndDeviceStatus::GetMac(void) { - return m_mac; + return m_mac; } EndDeviceStatus::ReceivedPacketList -EndDeviceStatus::GetReceivedPacketList () +EndDeviceStatus::GetReceivedPacketList() { - NS_LOG_FUNCTION_NOARGS (); - return m_receivedPacketList; + NS_LOG_FUNCTION_NOARGS(); + return m_receivedPacketList; } void -EndDeviceStatus::SetFirstReceiveWindowSpreadingFactor (uint8_t sf) +EndDeviceStatus::SetFirstReceiveWindowSpreadingFactor(uint8_t sf) { - NS_LOG_FUNCTION_NOARGS (); - m_firstReceiveWindowSpreadingFactor = sf; + NS_LOG_FUNCTION_NOARGS(); + m_firstReceiveWindowSpreadingFactor = sf; } void -EndDeviceStatus::SetFirstReceiveWindowFrequency (double frequency) +EndDeviceStatus::SetFirstReceiveWindowFrequency(double frequency) { - NS_LOG_FUNCTION_NOARGS (); - m_firstReceiveWindowFrequency = frequency; + NS_LOG_FUNCTION_NOARGS(); + m_firstReceiveWindowFrequency = frequency; } void -EndDeviceStatus::SetSecondReceiveWindowOffset (uint8_t offset) +EndDeviceStatus::SetSecondReceiveWindowOffset(uint8_t offset) { - NS_LOG_FUNCTION_NOARGS (); - m_secondReceiveWindowOffset = offset; + NS_LOG_FUNCTION_NOARGS(); + m_secondReceiveWindowOffset = offset; } void -EndDeviceStatus::SetSecondReceiveWindowFrequency (double frequency) +EndDeviceStatus::SetSecondReceiveWindowFrequency(double frequency) { - NS_LOG_FUNCTION_NOARGS (); - m_secondReceiveWindowFrequency = frequency; + NS_LOG_FUNCTION_NOARGS(); + m_secondReceiveWindowFrequency = frequency; } void -EndDeviceStatus::SetReplyMacHeader (LorawanMacHeader macHeader) +EndDeviceStatus::SetReplyMacHeader(LorawanMacHeader macHeader) { - NS_LOG_FUNCTION_NOARGS (); - m_reply.macHeader = macHeader; + NS_LOG_FUNCTION_NOARGS(); + m_reply.macHeader = macHeader; } void -EndDeviceStatus::SetReplyFrameHeader (LoraFrameHeader frameHeader) +EndDeviceStatus::SetReplyFrameHeader(LoraFrameHeader frameHeader) { - NS_LOG_FUNCTION_NOARGS (); - m_reply.frameHeader = frameHeader; + NS_LOG_FUNCTION_NOARGS(); + m_reply.frameHeader = frameHeader; } void -EndDeviceStatus::SetReplyPayload (Ptr replyPayload) +EndDeviceStatus::SetReplyPayload(Ptr replyPayload) { - NS_LOG_FUNCTION_NOARGS (); - m_reply.payload = replyPayload; + NS_LOG_FUNCTION_NOARGS(); + m_reply.payload = replyPayload; } /////////////////////// @@ -239,191 +242,191 @@ EndDeviceStatus::SetReplyPayload (Ptr replyPayload) /////////////////////// void -EndDeviceStatus::InsertReceivedPacket (Ptr receivedPacket, const Address &gwAddress) +EndDeviceStatus::InsertReceivedPacket(Ptr receivedPacket, const Address& gwAddress) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Create a copy of the packet - Ptr myPacket = receivedPacket->Copy (); + // Create a copy of the packet + Ptr myPacket = receivedPacket->Copy(); - // Extract the headers - LorawanMacHeader macHdr; - myPacket->RemoveHeader (macHdr); + // Extract the headers + LorawanMacHeader macHdr; + myPacket->RemoveHeader(macHdr); - LoraFrameHeader frameHdr; - frameHdr.SetAsUplink (); - myPacket->RemoveHeader (frameHdr); + LoraFrameHeader frameHdr; + frameHdr.SetAsUplink(); + myPacket->RemoveHeader(frameHdr); - // Update current parameters - LoraTag tag; - myPacket->RemovePacketTag (tag); - SetFirstReceiveWindowSpreadingFactor (tag.GetSpreadingFactor ()); - SetFirstReceiveWindowFrequency (tag.GetFrequency ()); + // Update current parameters + LoraTag tag; + myPacket->RemovePacketTag(tag); + SetFirstReceiveWindowSpreadingFactor(tag.GetSpreadingFactor()); + SetFirstReceiveWindowFrequency(tag.GetFrequency()); - // Update Information on the received packet - ReceivedPacketInfo info; - info.sf = tag.GetSpreadingFactor (); - info.frequency = tag.GetFrequency (); - info.packet = receivedPacket; + // Update Information on the received packet + ReceivedPacketInfo info; + info.sf = tag.GetSpreadingFactor(); + info.frequency = tag.GetFrequency(); + info.packet = receivedPacket; - double rcvPower = tag.GetReceivePower (); + double rcvPower = tag.GetReceivePower(); - // Perform insertion in list, also checking that the packet isn't already in - // the list (it could have been received by another GW already) + // Perform insertion in list, also checking that the packet isn't already in + // the list (it could have been received by another GW already) - // Start searching from the end - auto it = m_receivedPacketList.rbegin (); - for (; it != m_receivedPacketList.rend (); it++) + // Start searching from the end + auto it = m_receivedPacketList.rbegin(); + for (; it != m_receivedPacketList.rend(); it++) { - // Get the frame counter of the current packet to compare it with the - // newly received one - Ptr packetCopy = ((*it).first)->Copy (); - LorawanMacHeader currentMacHdr; - packetCopy->RemoveHeader (currentMacHdr); - LoraFrameHeader currentFrameHdr; - frameHdr.SetAsUplink (); - packetCopy->RemoveHeader (currentFrameHdr); - - NS_LOG_DEBUG ("Received packet's frame counter: " << unsigned(frameHdr.GetFCnt ()) - << "\nCurrent packet's frame counter: " - << unsigned(currentFrameHdr.GetFCnt ())); - - if (frameHdr.GetFCnt () == currentFrameHdr.GetFCnt ()) + // Get the frame counter of the current packet to compare it with the + // newly received one + Ptr packetCopy = ((*it).first)->Copy(); + LorawanMacHeader currentMacHdr; + packetCopy->RemoveHeader(currentMacHdr); + LoraFrameHeader currentFrameHdr; + frameHdr.SetAsUplink(); + packetCopy->RemoveHeader(currentFrameHdr); + + NS_LOG_DEBUG("Received packet's frame counter: " << unsigned(frameHdr.GetFCnt()) + << "\nCurrent packet's frame counter: " + << unsigned(currentFrameHdr.GetFCnt())); + + if (frameHdr.GetFCnt() == currentFrameHdr.GetFCnt()) { - NS_LOG_INFO ("Packet was already received by another gateway"); + NS_LOG_INFO("Packet was already received by another gateway"); - // This packet had already been received from another gateway: - // add this gateway's reception information. - GatewayList &gwList = it->second.gwList; + // This packet had already been received from another gateway: + // add this gateway's reception information. + GatewayList& gwList = it->second.gwList; - PacketInfoPerGw gwInfo; - gwInfo.receivedTime = Simulator::Now (); - gwInfo.rxPower = rcvPower; - gwInfo.gwAddress = gwAddress; - gwList.insert (std::pair (gwAddress, gwInfo)); + PacketInfoPerGw gwInfo; + gwInfo.receivedTime = Simulator::Now(); + gwInfo.rxPower = rcvPower; + gwInfo.gwAddress = gwAddress; + gwList.insert(std::pair(gwAddress, gwInfo)); - NS_LOG_DEBUG ("Size of gateway list: " << gwList.size ()); + NS_LOG_DEBUG("Size of gateway list: " << gwList.size()); - break; // Exit from the cycle + break; // Exit from the cycle } } - if (it == m_receivedPacketList.rend ()) + if (it == m_receivedPacketList.rend()) { - NS_LOG_INFO ("Packet was received for the first time"); - PacketInfoPerGw gwInfo; - gwInfo.receivedTime = Simulator::Now (); - gwInfo.rxPower = rcvPower; - gwInfo.gwAddress = gwAddress; - info.gwList.insert (std::pair (gwAddress, gwInfo)); - m_receivedPacketList.push_back ( - std::pair, ReceivedPacketInfo> (receivedPacket, info)); + NS_LOG_INFO("Packet was received for the first time"); + PacketInfoPerGw gwInfo; + gwInfo.receivedTime = Simulator::Now(); + gwInfo.rxPower = rcvPower; + gwInfo.gwAddress = gwAddress; + info.gwList.insert(std::pair(gwAddress, gwInfo)); + m_receivedPacketList.push_back( + std::pair, ReceivedPacketInfo>(receivedPacket, info)); } - NS_LOG_DEBUG (*this); + NS_LOG_DEBUG(*this); } EndDeviceStatus::ReceivedPacketInfo -EndDeviceStatus::GetLastReceivedPacketInfo (void) +EndDeviceStatus::GetLastReceivedPacketInfo(void) { - NS_LOG_FUNCTION_NOARGS (); - auto it = m_receivedPacketList.rbegin (); - if (it != m_receivedPacketList.rend ()) + NS_LOG_FUNCTION_NOARGS(); + auto it = m_receivedPacketList.rbegin(); + if (it != m_receivedPacketList.rend()) { - return it->second; + return it->second; } - else + else { - return EndDeviceStatus::ReceivedPacketInfo (); + return EndDeviceStatus::ReceivedPacketInfo(); } } -Ptr -EndDeviceStatus::GetLastPacketReceivedFromDevice (void) +Ptr +EndDeviceStatus::GetLastPacketReceivedFromDevice(void) { - NS_LOG_FUNCTION_NOARGS (); - auto it = m_receivedPacketList.rbegin (); - if (it != m_receivedPacketList.rend ()) + NS_LOG_FUNCTION_NOARGS(); + auto it = m_receivedPacketList.rbegin(); + if (it != m_receivedPacketList.rend()) { - return it->first; + return it->first; } - else + else { - return 0; + return 0; } } void -EndDeviceStatus::InitializeReply () +EndDeviceStatus::InitializeReply() { - NS_LOG_FUNCTION_NOARGS (); - m_reply = Reply (); - m_reply.needsReply = false; + NS_LOG_FUNCTION_NOARGS(); + m_reply = Reply(); + m_reply.needsReply = false; } void -EndDeviceStatus::AddMACCommand (Ptr macCommand) +EndDeviceStatus::AddMACCommand(Ptr macCommand) { - m_reply.frameHeader.AddCommand (macCommand); + m_reply.frameHeader.AddCommand(macCommand); } bool -EndDeviceStatus::HasReceiveWindowOpportunityScheduled () +EndDeviceStatus::HasReceiveWindowOpportunityScheduled() { - return m_receiveWindowEvent.IsRunning(); + return m_receiveWindowEvent.IsRunning(); } void -EndDeviceStatus::SetReceiveWindowOpportunity (EventId event) +EndDeviceStatus::SetReceiveWindowOpportunity(EventId event) { - m_receiveWindowEvent = event; + m_receiveWindowEvent = event; } void -EndDeviceStatus::RemoveReceiveWindowOpportunity (void) +EndDeviceStatus::RemoveReceiveWindowOpportunity(void) { - Simulator::Cancel(m_receiveWindowEvent); + Simulator::Cancel(m_receiveWindowEvent); } std::map -EndDeviceStatus::GetPowerGatewayMap (void) +EndDeviceStatus::GetPowerGatewayMap(void) { - // Create a map of the gateways - // Key: received power - // Value: address of the corresponding gateway - ReceivedPacketInfo info = m_receivedPacketList.back ().second; - GatewayList gwList = info.gwList; + // Create a map of the gateways + // Key: received power + // Value: address of the corresponding gateway + ReceivedPacketInfo info = m_receivedPacketList.back().second; + GatewayList gwList = info.gwList; - std::map gatewayPowers; + std::map gatewayPowers; - for (auto it = gwList.begin (); it != gwList.end (); it++) + for (auto it = gwList.begin(); it != gwList.end(); it++) { - Address currentGwAddress = (*it).first; - double currentRxPower = (*it).second.rxPower; - gatewayPowers.insert (std::pair (currentRxPower, currentGwAddress)); + Address currentGwAddress = (*it).first; + double currentRxPower = (*it).second.rxPower; + gatewayPowers.insert(std::pair(currentRxPower, currentGwAddress)); } - return gatewayPowers; + return gatewayPowers; } -std::ostream & -operator<< (std::ostream &os, const EndDeviceStatus &status) +std::ostream& +operator<<(std::ostream& os, const EndDeviceStatus& status) { - os << "Total packets received: " << status.m_receivedPacketList.size () << std::endl; + os << "Total packets received: " << status.m_receivedPacketList.size() << std::endl; - for (auto j = status.m_receivedPacketList.begin (); j != status.m_receivedPacketList.end (); j++) + for (auto j = status.m_receivedPacketList.begin(); j != status.m_receivedPacketList.end(); j++) { - EndDeviceStatus::ReceivedPacketInfo info = (*j).second; - EndDeviceStatus::GatewayList gatewayList = info.gwList; - Ptr pkt = (*j).first; - os << pkt << " " << gatewayList.size () << std::endl; - for (EndDeviceStatus::GatewayList::iterator k = gatewayList.begin (); k != gatewayList.end (); - k++) + EndDeviceStatus::ReceivedPacketInfo info = (*j).second; + EndDeviceStatus::GatewayList gatewayList = info.gwList; + Ptr pkt = (*j).first; + os << pkt << " " << gatewayList.size() << std::endl; + for (EndDeviceStatus::GatewayList::iterator k = gatewayList.begin(); k != gatewayList.end(); + k++) { - EndDeviceStatus::PacketInfoPerGw infoPerGw = (*k).second; - os << " " << infoPerGw.gwAddress << " " << infoPerGw.rxPower << std::endl; + EndDeviceStatus::PacketInfoPerGw infoPerGw = (*k).second; + os << " " << infoPerGw.gwAddress << " " << infoPerGw.rxPower << std::endl; } } - return os; + return os; } } // namespace lorawan } // namespace ns3 diff --git a/model/end-device-status.h b/model/end-device-status.h index f6d15bc136..22b35b1288 100644 --- a/model/end-device-status.h +++ b/model/end-device-status.h @@ -21,18 +21,21 @@ #ifndef END_DEVICE_STATUS_H #define END_DEVICE_STATUS_H +#include "class-a-end-device-lorawan-mac.h" +#include "lora-device-address.h" +#include "lora-frame-header.h" +#include "lora-net-device.h" +#include "lorawan-mac-header.h" + #include "ns3/object.h" -#include "ns3/lora-net-device.h" -#include "ns3/lora-device-address.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/lora-frame-header.h" #include "ns3/pointer.h" -#include "ns3/lora-frame-header.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class represents the Network Server's knowledge about an End Device in @@ -80,255 +83,251 @@ namespace lorawan { class EndDeviceStatus : public Object { - -public: - /********************/ - /* Reply management */ - /********************/ - - /** - * Structure representing the reply that the network server will send this - * device at the first opportunity. - */ - struct Reply - { - // The Mac Header to attach to the reply packet. - LorawanMacHeader macHeader; - - // The Frame Header to attach to the reply packet. - LoraFrameHeader frameHeader; - - // The data packet that will be sent as a reply. - Ptr payload; - - // Whether or not this device needs a reply - bool needsReply = false; - }; - - /** - * Whether the end device needs a reply. - * - * This is determined by looking at headers and payload of the Reply - * structure: if they are empty, no reply should be needed. - * - * \return A boolean value signaling if the end device needs a reply. - */ - bool NeedsReply (void); - - /** - * Get the reply packet. - * - * \return A pointer to the packet reply (data + headers). - */ - Ptr GetCompleteReplyPacket (void); - - /** - * Get the reply packet mac header. - * - * \return The packet reply mac header. - */ - LorawanMacHeader GetReplyMacHeader (void); - - /** - * Get the reply packet frame header. - * - * \return The packet reply frame header. - */ - LoraFrameHeader GetReplyFrameHeader (void); - - /** - * Get the data of the reply packet. - * - * \return A pointer to the packet reply. - */ - Ptr GetReplyPayload (void); - - /***********************************/ - /* Received packet list management */ - /***********************************/ - - /** - * Structure saving information regarding the packet reception in - * each gateway. - */ - struct PacketInfoPerGw - { - Address gwAddress; //!< Address of the gateway that received the packet. - Time receivedTime; //!< Time at which the packet was received by this gateway. - double rxPower; //!< Reception power of the packet at this gateway. - }; - - // List of gateways, with relative information - typedef std::map GatewayList; - - /** - * Structure saving information regarding all packet receptions. - */ - struct ReceivedPacketInfo - { - // Members - Ptr packet = 0; //!< The received packet - GatewayList gwList; //!< List of gateways that received this packet. - uint8_t sf; - double frequency; - }; - - typedef std::list, ReceivedPacketInfo> > - ReceivedPacketList; - - - /*******************************************/ - /* Proper EndDeviceStatus class definition */ - /*******************************************/ - - static TypeId GetTypeId (void); - - EndDeviceStatus (); - EndDeviceStatus (LoraDeviceAddress endDeviceAddress, - Ptr endDeviceMac); - virtual ~EndDeviceStatus (); - - /** - * Get the spreading factor this device is using in the first receive window. - * - * \return An unsigned 8-bit integer containing the spreading factor. - */ - uint8_t GetFirstReceiveWindowSpreadingFactor (void); - - /** - * Get the first window frequency of this device. - */ - double GetFirstReceiveWindowFrequency (void); - - /** - * Get the offset of spreading factor this device is using in the second - * receive window with respect to the first receive window. - * - * \return An unsigned 8-bit integer containing the spreading factor. - */ - uint8_t GetSecondReceiveWindowOffset (void); - - /** - * Return the second window frequency of this device. - * - */ - double GetSecondReceiveWindowFrequency (void); - - /** - * Get the received packet list. - * - * \return The received packet list. - */ - ReceivedPacketList GetReceivedPacketList (void); - - /** - * Set the spreading factor this device is using in the first receive window. - */ - void SetFirstReceiveWindowSpreadingFactor (uint8_t sf); - - /** - * Set the first window frequency of this device. - */ - void SetFirstReceiveWindowFrequency (double frequency); - - /** - * Set the spreading factor this device is using in the first receive window. - */ - void SetSecondReceiveWindowOffset (uint8_t offset); - - /** - * Set the second window frequency of this device. - */ - void SetSecondReceiveWindowFrequency (double frequency); - - /** - * Set the reply packet mac header. - */ - void SetReplyMacHeader (LorawanMacHeader macHeader); - - /** - * Set the reply packet frame header. - */ - void SetReplyFrameHeader (LoraFrameHeader frameHeader); - - /** - * Set the packet reply payload. - */ - void SetReplyPayload (Ptr replyPayload); - - Ptr GetMac (void); - - ////////////////////// - // Other methods // - ////////////////////// - - /** - * Insert a received packet in the packet list. - */ - void InsertReceivedPacket (Ptr receivedPacket, - const Address& gwAddress); - - /** - * Return the last packet that was received from this device. - */ - Ptr GetLastPacketReceivedFromDevice (void); - - /** - * Return the information about the last packet that was received from the - * device. - */ - EndDeviceStatus::ReceivedPacketInfo GetLastReceivedPacketInfo (void); - - /** - * Initialize reply. - */ - void InitializeReply (void); - - /** - * Add MAC command to the list. - */ - void AddMACCommand (Ptr macCommand); - - /** - * Update Gateway data when more then one gateway receive the same packet. - */ - void UpdateGatewayData (GatewayList gwList, Address gwAddress, double rcvPower); - - /** - * Returns whether we already decided we will schedule a transmission to this ED - */ - bool HasReceiveWindowOpportunityScheduled (); - - void SetReceiveWindowOpportunity (EventId event); - - void RemoveReceiveWindowOpportunity (void); - - /** - * Return an ordered list of the best gateways. - */ - std::map GetPowerGatewayMap (void); - - struct Reply m_reply; // m_mac; //!< Pointer to the MAC layer of this device + public: + /********************/ + /* Reply management */ + /********************/ + + /** + * Structure representing the reply that the network server will send this + * device at the first opportunity. + */ + struct Reply + { + // The Mac Header to attach to the reply packet. + LorawanMacHeader macHeader; + + // The Frame Header to attach to the reply packet. + LoraFrameHeader frameHeader; + + // The data packet that will be sent as a reply. + Ptr payload; + + // Whether or not this device needs a reply + bool needsReply = false; + }; + + /** + * Whether the end device needs a reply. + * + * This is determined by looking at headers and payload of the Reply + * structure: if they are empty, no reply should be needed. + * + * \return A boolean value signaling if the end device needs a reply. + */ + bool NeedsReply(void); + + /** + * Get the reply packet. + * + * \return A pointer to the packet reply (data + headers). + */ + Ptr GetCompleteReplyPacket(void); + + /** + * Get the reply packet mac header. + * + * \return The packet reply mac header. + */ + LorawanMacHeader GetReplyMacHeader(void); + + /** + * Get the reply packet frame header. + * + * \return The packet reply frame header. + */ + LoraFrameHeader GetReplyFrameHeader(void); + + /** + * Get the data of the reply packet. + * + * \return A pointer to the packet reply. + */ + Ptr GetReplyPayload(void); + + /***********************************/ + /* Received packet list management */ + /***********************************/ + + /** + * Structure saving information regarding the packet reception in + * each gateway. + */ + struct PacketInfoPerGw + { + Address gwAddress; //!< Address of the gateway that received the packet. + Time receivedTime; //!< Time at which the packet was received by this gateway. + double rxPower; //!< Reception power of the packet at this gateway. + }; + + // List of gateways, with relative information + typedef std::map GatewayList; + + /** + * Structure saving information regarding all packet receptions. + */ + struct ReceivedPacketInfo + { + // Members + Ptr packet = 0; //!< The received packet + GatewayList gwList; //!< List of gateways that received this packet. + uint8_t sf; + double frequency; + }; + + typedef std::list, ReceivedPacketInfo>> ReceivedPacketList; + + /*******************************************/ + /* Proper EndDeviceStatus class definition */ + /*******************************************/ + + static TypeId GetTypeId(void); + + EndDeviceStatus(); + EndDeviceStatus(LoraDeviceAddress endDeviceAddress, + Ptr endDeviceMac); + virtual ~EndDeviceStatus(); + + /** + * Get the spreading factor this device is using in the first receive window. + * + * \return An unsigned 8-bit integer containing the spreading factor. + */ + uint8_t GetFirstReceiveWindowSpreadingFactor(void); + + /** + * Get the first window frequency of this device. + */ + double GetFirstReceiveWindowFrequency(void); + + /** + * Get the offset of spreading factor this device is using in the second + * receive window with respect to the first receive window. + * + * \return An unsigned 8-bit integer containing the spreading factor. + */ + uint8_t GetSecondReceiveWindowOffset(void); + + /** + * Return the second window frequency of this device. + * + */ + double GetSecondReceiveWindowFrequency(void); + + /** + * Get the received packet list. + * + * \return The received packet list. + */ + ReceivedPacketList GetReceivedPacketList(void); + + /** + * Set the spreading factor this device is using in the first receive window. + */ + void SetFirstReceiveWindowSpreadingFactor(uint8_t sf); + + /** + * Set the first window frequency of this device. + */ + void SetFirstReceiveWindowFrequency(double frequency); + + /** + * Set the spreading factor this device is using in the first receive window. + */ + void SetSecondReceiveWindowOffset(uint8_t offset); + + /** + * Set the second window frequency of this device. + */ + void SetSecondReceiveWindowFrequency(double frequency); + + /** + * Set the reply packet mac header. + */ + void SetReplyMacHeader(LorawanMacHeader macHeader); + + /** + * Set the reply packet frame header. + */ + void SetReplyFrameHeader(LoraFrameHeader frameHeader); + + /** + * Set the packet reply payload. + */ + void SetReplyPayload(Ptr replyPayload); + + Ptr GetMac(void); + + ////////////////////// + // Other methods // + ////////////////////// + + /** + * Insert a received packet in the packet list. + */ + void InsertReceivedPacket(Ptr receivedPacket, const Address& gwAddress); + + /** + * Return the last packet that was received from this device. + */ + Ptr GetLastPacketReceivedFromDevice(void); + + /** + * Return the information about the last packet that was received from the + * device. + */ + EndDeviceStatus::ReceivedPacketInfo GetLastReceivedPacketInfo(void); + + /** + * Initialize reply. + */ + void InitializeReply(void); + + /** + * Add MAC command to the list. + */ + void AddMACCommand(Ptr macCommand); + + /** + * Update Gateway data when more then one gateway receive the same packet. + */ + void UpdateGatewayData(GatewayList gwList, Address gwAddress, double rcvPower); + + /** + * Returns whether we already decided we will schedule a transmission to this ED + */ + bool HasReceiveWindowOpportunityScheduled(); + + void SetReceiveWindowOpportunity(EventId event); + + void RemoveReceiveWindowOpportunity(void); + + /** + * Return an ordered list of the best gateways. + */ + std::map GetPowerGatewayMap(void); + + struct Reply m_reply; // m_mac; //!< Pointer to the MAC layer of this device }; -} +} // namespace lorawan -} +} // namespace ns3 #endif /* DEVICE_STATUS_H */ diff --git a/model/forwarder.cc b/model/forwarder.cc index 15c40f633e..f96e7970e3 100644 --- a/model/forwarder.cc +++ b/model/forwarder.cc @@ -18,97 +18,100 @@ * Author: Davide Magrin */ -#include "ns3/forwarder.h" +#include "forwarder.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("Forwarder"); +NS_LOG_COMPONENT_DEFINE("Forwarder"); -NS_OBJECT_ENSURE_REGISTERED (Forwarder); +NS_OBJECT_ENSURE_REGISTERED(Forwarder); TypeId -Forwarder::GetTypeId (void) +Forwarder::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::Forwarder") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::Forwarder") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -Forwarder::Forwarder () +Forwarder::Forwarder() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -Forwarder::~Forwarder () +Forwarder::~Forwarder() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -Forwarder::SetPointToPointNetDevice (Ptr - pointToPointNetDevice) +Forwarder::SetPointToPointNetDevice(Ptr pointToPointNetDevice) { - NS_LOG_FUNCTION (this << pointToPointNetDevice); + NS_LOG_FUNCTION(this << pointToPointNetDevice); - m_pointToPointNetDevice = pointToPointNetDevice; + m_pointToPointNetDevice = pointToPointNetDevice; } void -Forwarder::SetLoraNetDevice (Ptr loraNetDevice) +Forwarder::SetLoraNetDevice(Ptr loraNetDevice) { - NS_LOG_FUNCTION (this << loraNetDevice); + NS_LOG_FUNCTION(this << loraNetDevice); - m_loraNetDevice = loraNetDevice; + m_loraNetDevice = loraNetDevice; } bool -Forwarder::ReceiveFromLora (Ptr loraNetDevice, Ptr - packet, uint16_t protocol, const Address& sender) +Forwarder::ReceiveFromLora(Ptr loraNetDevice, + Ptr packet, + uint16_t protocol, + const Address& sender) { - NS_LOG_FUNCTION (this << packet << protocol << sender); + NS_LOG_FUNCTION(this << packet << protocol << sender); - Ptr packetCopy = packet->Copy (); + Ptr packetCopy = packet->Copy(); - m_pointToPointNetDevice->Send (packetCopy, - m_pointToPointNetDevice->GetBroadcast (), - 0x800); + m_pointToPointNetDevice->Send(packetCopy, m_pointToPointNetDevice->GetBroadcast(), 0x800); - return true; + return true; } bool -Forwarder::ReceiveFromPointToPoint (Ptr pointToPointNetDevice, - Ptr packet, uint16_t protocol, - const Address& sender) +Forwarder::ReceiveFromPointToPoint(Ptr pointToPointNetDevice, + Ptr packet, + uint16_t protocol, + const Address& sender) { - NS_LOG_FUNCTION (this << packet << protocol << sender); + NS_LOG_FUNCTION(this << packet << protocol << sender); - Ptr packetCopy = packet->Copy (); + Ptr packetCopy = packet->Copy(); - m_loraNetDevice->Send (packetCopy); + m_loraNetDevice->Send(packetCopy); - return true; + return true; } void -Forwarder::StartApplication (void) +Forwarder::StartApplication(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // TODO Make sure we are connected to both needed devices + // TODO Make sure we are connected to both needed devices } void -Forwarder::StopApplication (void) +Forwarder::StopApplication(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // TODO Get rid of callbacks + // TODO Get rid of callbacks } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/forwarder.h b/model/forwarder.h index 0523f20ee1..8636ce65d2 100644 --- a/model/forwarder.h +++ b/model/forwarder.h @@ -21,14 +21,17 @@ #ifndef FORWARDER_H #define FORWARDER_H +#include "lora-net-device.h" + #include "ns3/application.h" -#include "ns3/lora-net-device.h" -#include "ns3/point-to-point-net-device.h" -#include "ns3/nstime.h" #include "ns3/attribute.h" +#include "ns3/nstime.h" +#include "ns3/point-to-point-net-device.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This application forwards packets between NetDevices: @@ -36,64 +39,67 @@ namespace lorawan { */ class Forwarder : public Application { -public: - Forwarder (); - ~Forwarder (); - - static TypeId GetTypeId (void); - - /** - * Sets the device to use to communicate with the EDs. - * - * \param loraNetDevice The LoraNetDevice on this node. - */ - void SetLoraNetDevice (Ptr loraNetDevice); - - /** - * Sets the P2P device to use to communicate with the NS. - * - * \param pointToPointNetDevice The P2PNetDevice on this node. - */ - void SetPointToPointNetDevice (Ptr pointToPointNetDevice); - - /** - * Receive a packet from the LoraNetDevice. - * - * \param loraNetDevice The LoraNetDevice we received the packet from. - * \param packet The packet we received. - * \param protocol The protocol number associated to this packet. - * \param sender The address of the sender. - * \returns True if we can handle the packet, false otherwise. - */ - bool ReceiveFromLora (Ptr loraNetDevice, Ptr packet, - uint16_t protocol, const Address& sender); - - /** - * Receive a packet from the PointToPointNetDevice - */ - bool ReceiveFromPointToPoint (Ptr pointToPointNetDevice, - Ptr packet, uint16_t protocol, - const Address& sender); - - /** - * Start the application - */ - void StartApplication (void); - - /** - * Stop the application - */ - void StopApplication (void); - -private: - Ptr m_loraNetDevice; //!< Pointer to the node's LoraNetDevice - - Ptr m_pointToPointNetDevice; //!< Pointer to the - //!P2PNetDevice we use to - //!communicate with the NS + public: + Forwarder(); + ~Forwarder(); + + static TypeId GetTypeId(void); + + /** + * Sets the device to use to communicate with the EDs. + * + * \param loraNetDevice The LoraNetDevice on this node. + */ + void SetLoraNetDevice(Ptr loraNetDevice); + + /** + * Sets the P2P device to use to communicate with the NS. + * + * \param pointToPointNetDevice The P2PNetDevice on this node. + */ + void SetPointToPointNetDevice(Ptr pointToPointNetDevice); + + /** + * Receive a packet from the LoraNetDevice. + * + * \param loraNetDevice The LoraNetDevice we received the packet from. + * \param packet The packet we received. + * \param protocol The protocol number associated to this packet. + * \param sender The address of the sender. + * \returns True if we can handle the packet, false otherwise. + */ + bool ReceiveFromLora(Ptr loraNetDevice, + Ptr packet, + uint16_t protocol, + const Address& sender); + + /** + * Receive a packet from the PointToPointNetDevice + */ + bool ReceiveFromPointToPoint(Ptr pointToPointNetDevice, + Ptr packet, + uint16_t protocol, + const Address& sender); + + /** + * Start the application + */ + void StartApplication(void); + + /** + * Stop the application + */ + void StopApplication(void); + + private: + Ptr m_loraNetDevice; //!< Pointer to the node's LoraNetDevice + + Ptr m_pointToPointNetDevice; //!< Pointer to the + //! P2PNetDevice we use to + //! communicate with the NS }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* FORWARDER */ diff --git a/model/gateway-lora-phy.cc b/model/gateway-lora-phy.cc index 2bf8b211bf..e56ae0f11f 100644 --- a/model/gateway-lora-phy.cc +++ b/model/gateway-lora-phy.cc @@ -18,76 +18,82 @@ * Author: Davide Magrin */ -#include "ns3/gateway-lora-phy.h" +#include "gateway-lora-phy.h" + +#include "lora-tag.h" + #include "ns3/log-macros-enabled.h" -#include "ns3/lora-tag.h" -#include "ns3/simulator.h" #include "ns3/log.h" +#include "ns3/simulator.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("GatewayLoraPhy"); +NS_LOG_COMPONENT_DEFINE("GatewayLoraPhy"); -NS_OBJECT_ENSURE_REGISTERED (GatewayLoraPhy); +NS_OBJECT_ENSURE_REGISTERED(GatewayLoraPhy); /************************************** * ReceptionPath implementation * **************************************/ -GatewayLoraPhy::ReceptionPath::ReceptionPath () - : m_available (1), m_event (0), m_endReceiveEventId (EventId ()) +GatewayLoraPhy::ReceptionPath::ReceptionPath() + : m_available(1), + m_event(0), + m_endReceiveEventId(EventId()) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -GatewayLoraPhy::ReceptionPath::~ReceptionPath (void) +GatewayLoraPhy::ReceptionPath::~ReceptionPath(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } bool -GatewayLoraPhy::ReceptionPath::IsAvailable (void) +GatewayLoraPhy::ReceptionPath::IsAvailable(void) { - return m_available; + return m_available; } void -GatewayLoraPhy::ReceptionPath::Free (void) +GatewayLoraPhy::ReceptionPath::Free(void) { - m_available = true; - m_event = 0; - m_endReceiveEventId = EventId (); + m_available = true; + m_event = 0; + m_endReceiveEventId = EventId(); } void -GatewayLoraPhy::ReceptionPath::LockOnEvent (Ptr event) +GatewayLoraPhy::ReceptionPath::LockOnEvent(Ptr event) { - m_available = false; - m_event = event; + m_available = false; + m_event = event; } void -GatewayLoraPhy::ReceptionPath::SetEvent (Ptr event) +GatewayLoraPhy::ReceptionPath::SetEvent(Ptr event) { - m_event = event; + m_event = event; } Ptr -GatewayLoraPhy::ReceptionPath::GetEvent (void) +GatewayLoraPhy::ReceptionPath::GetEvent(void) { - return m_event; + return m_event; } EventId -GatewayLoraPhy::ReceptionPath::GetEndReceive (void) +GatewayLoraPhy::ReceptionPath::GetEndReceive(void) { - return m_endReceiveEventId; + return m_endReceiveEventId; } void -GatewayLoraPhy::ReceptionPath::SetEndReceive (EventId endReceiveEventId) +GatewayLoraPhy::ReceptionPath::SetEndReceive(EventId endReceiveEventId) { - m_endReceiveEventId = endReceiveEventId; + m_endReceiveEventId = endReceiveEventId; } /*********************************************************************** @@ -95,39 +101,41 @@ GatewayLoraPhy::ReceptionPath::SetEndReceive (EventId endReceiveEventId) ***********************************************************************/ TypeId -GatewayLoraPhy::GetTypeId (void) +GatewayLoraPhy::GetTypeId(void) { - static TypeId tid = - TypeId ("ns3::GatewayLoraPhy") - .SetParent () - .SetGroupName ("lorawan") - .AddTraceSource ( - "NoReceptionBecauseTransmitting", - "Trace source indicating a packet " - "could not be correctly received because" - "the GW is in transmission mode", - MakeTraceSourceAccessor (&GatewayLoraPhy::m_noReceptionBecauseTransmitting), - "ns3::Packet::TracedCallback") - .AddTraceSource ("LostPacketBecauseNoMoreReceivers", - "Trace source indicating a packet " - "could not be correctly received because" - "there are no more demodulators available", - MakeTraceSourceAccessor (&GatewayLoraPhy::m_noMoreDemodulators), - "ns3::Packet::TracedCallback") - .AddTraceSource ("OccupiedReceptionPaths", "Number of currently occupied reception paths", - MakeTraceSourceAccessor (&GatewayLoraPhy::m_occupiedReceptionPaths), - "ns3::TracedValueCallback::Int"); - return tid; + static TypeId tid = + TypeId("ns3::GatewayLoraPhy") + .SetParent() + .SetGroupName("lorawan") + .AddTraceSource( + "NoReceptionBecauseTransmitting", + "Trace source indicating a packet " + "could not be correctly received because" + "the GW is in transmission mode", + MakeTraceSourceAccessor(&GatewayLoraPhy::m_noReceptionBecauseTransmitting), + "ns3::Packet::TracedCallback") + .AddTraceSource("LostPacketBecauseNoMoreReceivers", + "Trace source indicating a packet " + "could not be correctly received because" + "there are no more demodulators available", + MakeTraceSourceAccessor(&GatewayLoraPhy::m_noMoreDemodulators), + "ns3::Packet::TracedCallback") + .AddTraceSource("OccupiedReceptionPaths", + "Number of currently occupied reception paths", + MakeTraceSourceAccessor(&GatewayLoraPhy::m_occupiedReceptionPaths), + "ns3::TracedValueCallback::Int"); + return tid; } -GatewayLoraPhy::GatewayLoraPhy () : m_isTransmitting (false) +GatewayLoraPhy::GatewayLoraPhy() + : m_isTransmitting(false) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -GatewayLoraPhy::~GatewayLoraPhy () +GatewayLoraPhy::~GatewayLoraPhy() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } // Uplink sensitivity (Source: SX1301 datasheet) @@ -135,57 +143,57 @@ GatewayLoraPhy::~GatewayLoraPhy () const double GatewayLoraPhy::sensitivity[6] = {-130.0, -132.5, -135.0, -137.5, -140.0, -142.5}; void -GatewayLoraPhy::AddReceptionPath () +GatewayLoraPhy::AddReceptionPath() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_receptionPaths.push_back (Create ()); + m_receptionPaths.push_back(Create()); } void -GatewayLoraPhy::ResetReceptionPaths (void) +GatewayLoraPhy::ResetReceptionPaths(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_receptionPaths.clear (); + m_receptionPaths.clear(); } void -GatewayLoraPhy::TxFinished (Ptr packet) +GatewayLoraPhy::TxFinished(Ptr packet) { - m_isTransmitting = false; + m_isTransmitting = false; } bool -GatewayLoraPhy::IsTransmitting (void) +GatewayLoraPhy::IsTransmitting(void) { - return m_isTransmitting; + return m_isTransmitting; } void -GatewayLoraPhy::AddFrequency (double frequencyMHz) +GatewayLoraPhy::AddFrequency(double frequencyMHz) { - NS_LOG_FUNCTION (this << frequencyMHz); + NS_LOG_FUNCTION(this << frequencyMHz); - m_frequencies.push_back (frequencyMHz); + m_frequencies.push_back(frequencyMHz); - NS_ASSERT (m_frequencies.size () <= 8); + NS_ASSERT(m_frequencies.size() <= 8); } bool -GatewayLoraPhy::IsOnFrequency (double frequencyMHz) +GatewayLoraPhy::IsOnFrequency(double frequencyMHz) { - NS_LOG_FUNCTION (this << frequencyMHz); + NS_LOG_FUNCTION(this << frequencyMHz); - // Look into our list of frequencies - for (auto &f : m_frequencies) + // Look into our list of frequencies + for (auto& f : m_frequencies) { - if (f == frequencyMHz) + if (f == frequencyMHz) { - return true; + return true; } } - return false; + return false; } } // namespace lorawan } // namespace ns3 diff --git a/model/gateway-lora-phy.h b/model/gateway-lora-phy.h index a4b6f8a193..d60ad28136 100644 --- a/model/gateway-lora-phy.h +++ b/model/gateway-lora-phy.h @@ -21,17 +21,21 @@ #ifndef GATEWAY_LORA_PHY_H #define GATEWAY_LORA_PHY_H -#include "ns3/object.h" -#include "ns3/net-device.h" -#include "ns3/nstime.h" +#include "lora-phy.h" + #include "ns3/mobility-model.h" +#include "ns3/net-device.h" #include "ns3/node.h" -#include "ns3/lora-phy.h" +#include "ns3/nstime.h" +#include "ns3/object.h" #include "ns3/traced-value.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; @@ -47,166 +51,170 @@ class LoraChannel; */ class GatewayLoraPhy : public LoraPhy { -public: - static TypeId GetTypeId (void); - - GatewayLoraPhy (); - virtual ~GatewayLoraPhy (); - - virtual void StartReceive (Ptr packet, double rxPowerDbm, uint8_t sf, Time duration, - double frequencyMHz) = 0; - - virtual void EndReceive (Ptr packet, Ptr event) = 0; - - virtual void Send (Ptr packet, LoraTxParameters txParams, double frequencyMHz, - double txPowerDbm) = 0; - - virtual void TxFinished (Ptr packet); + public: + static TypeId GetTypeId(void); - bool IsTransmitting (void); + GatewayLoraPhy(); + virtual ~GatewayLoraPhy(); - virtual bool IsOnFrequency (double frequencyMHz); + virtual void StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz) = 0; - /** - * Add a reception path, locked on a specific frequency. - */ - void AddReceptionPath (); + virtual void EndReceive(Ptr packet, Ptr event) = 0; - /** - * Reset the list of reception paths. - * - * This method deletes all currently available ReceptionPath objects. - */ - void ResetReceptionPaths (void); + virtual void Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm) = 0; - /** - * Add a frequency to the list of frequencies we are listening to. - */ - void AddFrequency (double frequencyMHz); + virtual void TxFinished(Ptr packet); - /** - * A vector containing the sensitivities required to correctly decode - * different spreading factors. - */ - static const double sensitivity[6]; + bool IsTransmitting(void); -protected: - /** - * This class represents a configurable reception path. - * - * Differently from EndDeviceLoraPhys, these do not need to be configured to - * listen for a certain SF. ReceptionPaths be either locked on an event or - * free. - */ - class ReceptionPath : public SimpleRefCount - { + virtual bool IsOnFrequency(double frequencyMHz); - public: /** - * Constructor. + * Add a reception path, locked on a specific frequency. */ - ReceptionPath (); - - ~ReceptionPath (); + void AddReceptionPath(); /** - * Query whether this reception path is available to lock on a signal. + * Reset the list of reception paths. * - * \return True if its current state is free, false if it's currently locked. + * This method deletes all currently available ReceptionPath objects. */ - bool IsAvailable (void); + void ResetReceptionPaths(void); /** - * Set this reception path as available. - * - * This function sets the m_available variable as true, and deletes the - * LoraInterferenceHelper Event this ReceivePath was previously locked on. + * Add a frequency to the list of frequencies we are listening to. */ - void Free (void); + void AddFrequency(double frequencyMHz); /** - * Set this reception path as not available and lock it on the - * provided event. - * - * \param event The LoraInterferenceHelper Event to lock on. + * A vector containing the sensitivities required to correctly decode + * different spreading factors. */ - void LockOnEvent (Ptr event); + static const double sensitivity[6]; + protected: /** - * Set the event this reception path is currently on. + * This class represents a configurable reception path. * - * \param event the event to lock this ReceptionPath on. + * Differently from EndDeviceLoraPhys, these do not need to be configured to + * listen for a certain SF. ReceptionPaths be either locked on an event or + * free. */ - void SetEvent (Ptr event); + class ReceptionPath : public SimpleRefCount + { + public: + /** + * Constructor. + */ + ReceptionPath(); + + ~ReceptionPath(); + + /** + * Query whether this reception path is available to lock on a signal. + * + * \return True if its current state is free, false if it's currently locked. + */ + bool IsAvailable(void); + + /** + * Set this reception path as available. + * + * This function sets the m_available variable as true, and deletes the + * LoraInterferenceHelper Event this ReceivePath was previously locked on. + */ + void Free(void); + + /** + * Set this reception path as not available and lock it on the + * provided event. + * + * \param event The LoraInterferenceHelper Event to lock on. + */ + void LockOnEvent(Ptr event); + + /** + * Set the event this reception path is currently on. + * + * \param event the event to lock this ReceptionPath on. + */ + void SetEvent(Ptr event); + + /** + * Get the event this reception path is currently on. + * + * \returns 0 if no event is currently being received, a pointer to + * the event otherwise. + */ + Ptr GetEvent(void); + + /** + * Get the EventId of the EndReceive call associated to this ReceptionPath's + * packet. + */ + EventId GetEndReceive(void); + + /** + * Set the EventId of the EndReceive call associated to this ReceptionPath's + * packet. + */ + void SetEndReceive(EventId endReceiveEventId); + + private: + /** + * Whether this reception path is available to lock on a signal or not. + */ + bool m_available; + + /** + * The event this reception path is currently locked on. + */ + Ptr m_event; + + /** + * The EventId associated of the call to EndReceive that is scheduled to + * happen when the packet this ReceivePath is locked on finishes reception. + */ + EventId m_endReceiveEventId; + }; /** - * Get the event this reception path is currently on. - * - * \returns 0 if no event is currently being received, a pointer to - * the event otherwise. + * A list containing the various parallel receivers that are managed by this + * Gateway. */ - Ptr GetEvent (void); + std::list> m_receptionPaths; /** - * Get the EventId of the EndReceive call associated to this ReceptionPath's - * packet. + * The number of occupied reception paths. */ - EventId GetEndReceive (void); + TracedValue m_occupiedReceptionPaths; /** - * Set the EventId of the EndReceive call associated to this ReceptionPath's - * packet. + * Trace source that is fired when a packet cannot be received because all + * available ReceivePath instances are busy. + * + * \see class CallBackTraceSource */ - void SetEndReceive (EventId endReceiveEventId); + TracedCallback, uint32_t> m_noMoreDemodulators; - private: /** - * Whether this reception path is available to lock on a signal or not. + * Trace source that is fired when a packet cannot be received because + * the Gateway is in transmission state. + * + * \see class CallBackTraceSource */ - bool m_available; + TracedCallback, uint32_t> m_noReceptionBecauseTransmitting; - /** - * The event this reception path is currently locked on. - */ - Ptr m_event; + bool m_isTransmitting; //!< Flag indicating whether a transmission is going on - /** - * The EventId associated of the call to EndReceive that is scheduled to - * happen when the packet this ReceivePath is locked on finishes reception. - */ - EventId m_endReceiveEventId; - }; - - /** - * A list containing the various parallel receivers that are managed by this - * Gateway. - */ - std::list> m_receptionPaths; - - /** - * The number of occupied reception paths. - */ - TracedValue m_occupiedReceptionPaths; - - /** - * Trace source that is fired when a packet cannot be received because all - * available ReceivePath instances are busy. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_noMoreDemodulators; - - /** - * Trace source that is fired when a packet cannot be received because - * the Gateway is in transmission state. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_noReceptionBecauseTransmitting; - - bool m_isTransmitting; //!< Flag indicating whether a transmission is going on - - std::list m_frequencies; + std::list m_frequencies; }; } // namespace lorawan diff --git a/model/gateway-lorawan-mac.cc b/model/gateway-lorawan-mac.cc index 1216bc701a..3134b08b55 100644 --- a/model/gateway-lorawan-mac.cc +++ b/model/gateway-lorawan-mac.cc @@ -18,142 +18,145 @@ * Author: Davide Magrin */ -#include "ns3/gateway-lorawan-mac.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/lora-net-device.h" -#include "ns3/lora-frame-header.h" +#include "gateway-lorawan-mac.h" + +#include "lora-frame-header.h" +#include "lora-net-device.h" +#include "lorawan-mac-header.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("GatewayLorawanMac"); +NS_LOG_COMPONENT_DEFINE("GatewayLorawanMac"); -NS_OBJECT_ENSURE_REGISTERED (GatewayLorawanMac); +NS_OBJECT_ENSURE_REGISTERED(GatewayLorawanMac); TypeId -GatewayLorawanMac::GetTypeId (void) +GatewayLorawanMac::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::GatewayLorawanMac") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::GatewayLorawanMac") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -GatewayLorawanMac::GatewayLorawanMac () +GatewayLorawanMac::GatewayLorawanMac() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -GatewayLorawanMac::~GatewayLorawanMac () +GatewayLorawanMac::~GatewayLorawanMac() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -GatewayLorawanMac::Send (Ptr packet) +GatewayLorawanMac::Send(Ptr packet) { - NS_LOG_FUNCTION (this << packet); - - // Get DataRate to send this packet with - LoraTag tag; - packet->RemovePacketTag (tag); - uint8_t dataRate = tag.GetDataRate (); - double frequency = tag.GetFrequency (); - NS_LOG_DEBUG ("DR: " << unsigned (dataRate)); - NS_LOG_DEBUG ("SF: " << unsigned (GetSfFromDataRate (dataRate))); - NS_LOG_DEBUG ("BW: " << GetBandwidthFromDataRate (dataRate)); - NS_LOG_DEBUG ("Freq: " << frequency << " MHz"); - packet->AddPacketTag (tag); - - // Make sure we can transmit this packet - if (m_channelHelper.GetWaitingTime(CreateObject (frequency)) > Time(0)) + NS_LOG_FUNCTION(this << packet); + + // Get DataRate to send this packet with + LoraTag tag; + packet->RemovePacketTag(tag); + uint8_t dataRate = tag.GetDataRate(); + double frequency = tag.GetFrequency(); + NS_LOG_DEBUG("DR: " << unsigned(dataRate)); + NS_LOG_DEBUG("SF: " << unsigned(GetSfFromDataRate(dataRate))); + NS_LOG_DEBUG("BW: " << GetBandwidthFromDataRate(dataRate)); + NS_LOG_DEBUG("Freq: " << frequency << " MHz"); + packet->AddPacketTag(tag); + + // Make sure we can transmit this packet + if (m_channelHelper.GetWaitingTime(CreateObject(frequency)) > Time(0)) { - // We cannot send now! - NS_LOG_WARN ("Trying to send a packet but Duty Cycle won't allow it. Aborting."); - return; + // We cannot send now! + NS_LOG_WARN("Trying to send a packet but Duty Cycle won't allow it. Aborting."); + return; } - LoraTxParameters params; - params.sf = GetSfFromDataRate (dataRate); - params.headerDisabled = false; - params.codingRate = 1; - params.bandwidthHz = GetBandwidthFromDataRate (dataRate); - params.nPreamble = 8; - params.crcEnabled = 1; - params.lowDataRateOptimizationEnabled = LoraPhy::GetTSym (params) > MilliSeconds (16) ? true : false; + LoraTxParameters params; + params.sf = GetSfFromDataRate(dataRate); + params.headerDisabled = false; + params.codingRate = 1; + params.bandwidthHz = GetBandwidthFromDataRate(dataRate); + params.nPreamble = 8; + params.crcEnabled = 1; + params.lowDataRateOptimizationEnabled = + LoraPhy::GetTSym(params) > MilliSeconds(16) ? true : false; - // Get the duration - Time duration = m_phy->GetOnAirTime (packet, params); + // Get the duration + Time duration = m_phy->GetOnAirTime(packet, params); - NS_LOG_DEBUG ("Duration: " << duration.GetSeconds ()); + NS_LOG_DEBUG("Duration: " << duration.GetSeconds()); - // Find the channel with the desired frequency - double sendingPower = m_channelHelper.GetTxPowerForChannel - (CreateObject (frequency)); + // Find the channel with the desired frequency + double sendingPower = + m_channelHelper.GetTxPowerForChannel(CreateObject(frequency)); - // Add the event to the channelHelper to keep track of duty cycle - m_channelHelper.AddEvent (duration, CreateObject - (frequency)); + // Add the event to the channelHelper to keep track of duty cycle + m_channelHelper.AddEvent(duration, CreateObject(frequency)); - // Send the packet to the PHY layer to send it on the channel - m_phy->Send (packet, params, frequency, sendingPower); + // Send the packet to the PHY layer to send it on the channel + m_phy->Send(packet, params, frequency, sendingPower); - m_sentNewPacket (packet); + m_sentNewPacket(packet); } bool -GatewayLorawanMac::IsTransmitting (void) +GatewayLorawanMac::IsTransmitting(void) { - return m_phy->IsTransmitting (); + return m_phy->IsTransmitting(); } void -GatewayLorawanMac::Receive (Ptr packet) +GatewayLorawanMac::Receive(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // Make a copy of the packet to work on - Ptr packetCopy = packet->Copy (); + // Make a copy of the packet to work on + Ptr packetCopy = packet->Copy(); - // Only forward the packet if it's uplink - LorawanMacHeader macHdr; - packetCopy->PeekHeader (macHdr); + // Only forward the packet if it's uplink + LorawanMacHeader macHdr; + packetCopy->PeekHeader(macHdr); - if (macHdr.IsUplink ()) + if (macHdr.IsUplink()) { - m_device->GetObject ()->Receive (packetCopy); + m_device->GetObject()->Receive(packetCopy); - NS_LOG_DEBUG ("Received packet: " << packet); + NS_LOG_DEBUG("Received packet: " << packet); - m_receivedPacket (packet); + m_receivedPacket(packet); } - else + else { - NS_LOG_DEBUG ("Not forwarding downlink message to NetDevice"); + NS_LOG_DEBUG("Not forwarding downlink message to NetDevice"); } } void -GatewayLorawanMac::FailedReception (Ptr packet) +GatewayLorawanMac::FailedReception(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); } void -GatewayLorawanMac::TxFinished (Ptr packet) +GatewayLorawanMac::TxFinished(Ptr packet) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } Time -GatewayLorawanMac::GetWaitingTime (double frequency) +GatewayLorawanMac::GetWaitingTime(double frequency) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_channelHelper.GetWaitingTime (CreateObject - (frequency)); -} -} + return m_channelHelper.GetWaitingTime(CreateObject(frequency)); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/gateway-lorawan-mac.h b/model/gateway-lorawan-mac.h index 30ae511c82..2e98d71cef 100644 --- a/model/gateway-lorawan-mac.h +++ b/model/gateway-lorawan-mac.h @@ -21,46 +21,49 @@ #ifndef GATEWAY_LORAWAN_MAC_H #define GATEWAY_LORAWAN_MAC_H -#include "ns3/lorawan-mac.h" -#include "ns3/lora-tag.h" +#include "lora-tag.h" +#include "lorawan-mac.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class GatewayLorawanMac : public LorawanMac { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); + + GatewayLorawanMac(); + virtual ~GatewayLorawanMac(); - GatewayLorawanMac (); - virtual ~GatewayLorawanMac (); + // Implementation of the LorawanMac interface + virtual void Send(Ptr packet); - // Implementation of the LorawanMac interface - virtual void Send (Ptr packet); + // Implementation of the LorawanMac interface + bool IsTransmitting(void); - // Implementation of the LorawanMac interface - bool IsTransmitting (void); + // Implementation of the LorawanMac interface + virtual void Receive(Ptr packet); - // Implementation of the LorawanMac interface - virtual void Receive (Ptr packet); + // Implementation of the LorawanMac interface + virtual void FailedReception(Ptr packet); - // Implementation of the LorawanMac interface - virtual void FailedReception (Ptr packet); + // Implementation of the LorawanMac interface + virtual void TxFinished(Ptr packet); - // Implementation of the LorawanMac interface - virtual void TxFinished (Ptr packet); + /** + * Return the next time at which we will be able to transmit. + * + * \return The next transmission time. + */ + Time GetWaitingTime(double frequency); - /** - * Return the next time at which we will be able to transmit. - * - * \return The next transmission time. - */ - Time GetWaitingTime (double frequency); -private: -protected: + private: + protected: }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* GATEWAY_LORAWAN_MAC_H */ diff --git a/model/gateway-status.cc b/model/gateway-status.cc index 05d906181f..dccc9eeed7 100644 --- a/model/gateway-status.cc +++ b/model/gateway-status.cc @@ -18,115 +18,116 @@ * Author: Davide Magrin */ -#include "ns3/gateway-status.h" +#include "gateway-status.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("GatewayStatus"); +NS_LOG_COMPONENT_DEFINE("GatewayStatus"); TypeId -GatewayStatus::GetTypeId (void) +GatewayStatus::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::GatewayStatus") - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::GatewayStatus").AddConstructor().SetGroupName("lorawan"); + return tid; } - -GatewayStatus::GatewayStatus () +GatewayStatus::GatewayStatus() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -GatewayStatus::~GatewayStatus () +GatewayStatus::~GatewayStatus() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -GatewayStatus::GatewayStatus (Address address, Ptr netDevice, - Ptr gwMac) : - m_address (address), - m_netDevice (netDevice), - m_gatewayMac (gwMac), - m_nextTransmissionTime (Seconds (0)) +GatewayStatus::GatewayStatus(Address address, + Ptr netDevice, + Ptr gwMac) + : m_address(address), + m_netDevice(netDevice), + m_gatewayMac(gwMac), + m_nextTransmissionTime(Seconds(0)) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } Address -GatewayStatus::GetAddress () +GatewayStatus::GetAddress() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_address; + return m_address; } void -GatewayStatus::SetAddress (Address address) +GatewayStatus::SetAddress(Address address) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_address = address; + m_address = address; } Ptr -GatewayStatus::GetNetDevice () +GatewayStatus::GetNetDevice() { - return m_netDevice; + return m_netDevice; } void -GatewayStatus::SetNetDevice (Ptr netDevice) +GatewayStatus::SetNetDevice(Ptr netDevice) { - m_netDevice = netDevice; + m_netDevice = netDevice; } Ptr -GatewayStatus::GetGatewayMac (void) +GatewayStatus::GetGatewayMac(void) { - return m_gatewayMac; + return m_gatewayMac; } bool -GatewayStatus::IsAvailableForTransmission (double frequency) +GatewayStatus::IsAvailableForTransmission(double frequency) { - // We can't send multiple packets at once, see SX1301 V2.01 page 29 + // We can't send multiple packets at once, see SX1301 V2.01 page 29 - // Check that the gateway was not already "booked" - if (m_nextTransmissionTime > Simulator::Now () - MilliSeconds (1)) + // Check that the gateway was not already "booked" + if (m_nextTransmissionTime > Simulator::Now() - MilliSeconds(1)) { - NS_LOG_INFO ("This gateway is already booked for a transmission"); - return false; + NS_LOG_INFO("This gateway is already booked for a transmission"); + return false; } - // Check that the gateway is not already in TX mode - if (m_gatewayMac->IsTransmitting ()) + // Check that the gateway is not already in TX mode + if (m_gatewayMac->IsTransmitting()) { - NS_LOG_INFO ("This gateway is currently transmitting"); - return false; + NS_LOG_INFO("This gateway is currently transmitting"); + return false; } - // Check that the gateway is not constrained by the duty cycle - Time waitingTime = m_gatewayMac->GetWaitingTime (frequency); - if (waitingTime > Seconds (0)) + // Check that the gateway is not constrained by the duty cycle + Time waitingTime = m_gatewayMac->GetWaitingTime(frequency); + if (waitingTime > Seconds(0)) { - NS_LOG_INFO ("Gateway cannot be used because of duty cycle"); - NS_LOG_INFO ("Waiting time at current GW: " << waitingTime.GetSeconds () - << " seconds"); + NS_LOG_INFO("Gateway cannot be used because of duty cycle"); + NS_LOG_INFO("Waiting time at current GW: " << waitingTime.GetSeconds() << " seconds"); - return false; + return false; } - return true; + return true; } void -GatewayStatus::SetNextTransmissionTime (Time nextTransmissionTime) +GatewayStatus::SetNextTransmissionTime(Time nextTransmissionTime) { - m_nextTransmissionTime = nextTransmissionTime; -} -} + m_nextTransmissionTime = nextTransmissionTime; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/gateway-status.h b/model/gateway-status.h index 759b113476..bc58769fae 100644 --- a/model/gateway-status.h +++ b/model/gateway-status.h @@ -21,76 +21,80 @@ #ifndef GATEWAY_STATUS_H #define GATEWAY_STATUS_H -#include "ns3/object.h" +#include "gateway-lorawan-mac.h" + #include "ns3/address.h" #include "ns3/net-device.h" -#include "ns3/gateway-lorawan-mac.h" +#include "ns3/object.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class GatewayStatus : public Object { -public: - static TypeId GetTypeId (void); - - GatewayStatus (); - GatewayStatus (Address address, Ptr netDevice, Ptr gwMac); - virtual ~GatewayStatus (); - - /** - * Get this gateway's P2P link address. - */ - Address GetAddress (); - - /** - * Set this gateway's P2P link address. - */ - void SetAddress (Address address); - - /** - * Get the NetDevice through which it's possible to contact this gateway from the server. - */ - Ptr GetNetDevice (); - - /** - * Set the NetDevice through which it's possible to contact this gateway from the server. - */ - void SetNetDevice (Ptr netDevice); - - /** - * Get a pointer to this gateway's MAC instance. - */ - Ptr GetGatewayMac (void); - - /** - * Set a pointer to this gateway's MAC instance. - */ - // void SetGatewayMac (Ptr gwMac); - - /** - * Query whether or not this gateway is available for immediate transmission - * on this frequency. - * - * \param frequency The frequency at which the gateway's availability should - * be queried. - * \return True if the gateway's available, false otherwise. - */ - bool IsAvailableForTransmission (double frequency); - - void SetNextTransmissionTime (Time nextTransmissionTime); - // Time GetNextTransmissionTime (void); - -private: - Address m_address; //!< The Address of the P2PNetDevice of this gateway - - Ptr m_netDevice; //!< The NetDevice through which to reach this gateway from the server - - Ptr m_gatewayMac; //!< The Mac layer of the gateway - - Time m_nextTransmissionTime; //!< This gateway's next transmission time + public: + static TypeId GetTypeId(void); + + GatewayStatus(); + GatewayStatus(Address address, Ptr netDevice, Ptr gwMac); + virtual ~GatewayStatus(); + + /** + * Get this gateway's P2P link address. + */ + Address GetAddress(); + + /** + * Set this gateway's P2P link address. + */ + void SetAddress(Address address); + + /** + * Get the NetDevice through which it's possible to contact this gateway from the server. + */ + Ptr GetNetDevice(); + + /** + * Set the NetDevice through which it's possible to contact this gateway from the server. + */ + void SetNetDevice(Ptr netDevice); + + /** + * Get a pointer to this gateway's MAC instance. + */ + Ptr GetGatewayMac(void); + + /** + * Set a pointer to this gateway's MAC instance. + */ + // void SetGatewayMac (Ptr gwMac); + + /** + * Query whether or not this gateway is available for immediate transmission + * on this frequency. + * + * \param frequency The frequency at which the gateway's availability should + * be queried. + * \return True if the gateway's available, false otherwise. + */ + bool IsAvailableForTransmission(double frequency); + + void SetNextTransmissionTime(Time nextTransmissionTime); + // Time GetNextTransmissionTime (void); + + private: + Address m_address; //!< The Address of the P2PNetDevice of this gateway + + Ptr + m_netDevice; //!< The NetDevice through which to reach this gateway from the server + + Ptr m_gatewayMac; //!< The Mac layer of the gateway + + Time m_nextTransmissionTime; //!< This gateway's next transmission time }; -} +} // namespace lorawan -} +} // namespace ns3 #endif /* DEVICE_STATUS_H */ diff --git a/model/hex-grid-position-allocator.cc b/model/hex-grid-position-allocator.cc index 818bff6a79..95061a5ca6 100644 --- a/model/hex-grid-position-allocator.cc +++ b/model/hex-grid-position-allocator.cc @@ -16,146 +16,149 @@ * Author: Davide Magrin */ -#include "ns3/log.h" -#include "ns3/hex-grid-position-allocator.h" +#include "hex-grid-position-allocator.h" + #include "ns3/double.h" +#include "ns3/log.h" -namespace ns3 { +namespace ns3 +{ - NS_LOG_COMPONENT_DEFINE ("HexGridPositionAllocator"); +NS_LOG_COMPONENT_DEFINE("HexGridPositionAllocator"); - NS_OBJECT_ENSURE_REGISTERED (HexGridPositionAllocator); +NS_OBJECT_ENSURE_REGISTERED(HexGridPositionAllocator); - TypeId - HexGridPositionAllocator::GetTypeId (void) - { - static TypeId tid = TypeId ("ns3::HexGridPositionAllocator") - .SetParent () - .AddConstructor () - .SetGroupName ("Lora") - .AddAttribute ("Radius", "The radius of a single hexagon", - DoubleValue (6000), - MakeDoubleAccessor (&HexGridPositionAllocator::m_radius), - MakeDoubleChecker ()); +TypeId +HexGridPositionAllocator::GetTypeId(void) +{ + static TypeId tid = TypeId("ns3::HexGridPositionAllocator") + .SetParent() + .AddConstructor() + .SetGroupName("Lora") + .AddAttribute("Radius", + "The radius of a single hexagon", + DoubleValue(6000), + MakeDoubleAccessor(&HexGridPositionAllocator::m_radius), + MakeDoubleChecker()); return tid; - } +} - HexGridPositionAllocator::HexGridPositionAllocator () : - m_radius (6000) - { - NS_LOG_FUNCTION_NOARGS (); +HexGridPositionAllocator::HexGridPositionAllocator() + : m_radius(6000) +{ + NS_LOG_FUNCTION_NOARGS(); // Create the first position - m_positions.push_back (Vector (0.0,0.0,0.0)); + m_positions.push_back(Vector(0.0, 0.0, 0.0)); // Add rings - for (int i = 0; i < 20; i++) { - m_positions = AddRing(m_positions); + for (int i = 0; i < 20; i++) + { + m_positions = AddRing(m_positions); } // Set the iterator m_next = m_positions.begin(); - } +} - HexGridPositionAllocator::HexGridPositionAllocator (double radius) : - m_radius (radius) - { - NS_LOG_FUNCTION_NOARGS (); +HexGridPositionAllocator::HexGridPositionAllocator(double radius) + : m_radius(radius) +{ + NS_LOG_FUNCTION_NOARGS(); // Create the first position - m_positions.push_back (Vector (0.0,0.0,0.0)); + m_positions.push_back(Vector(0.0, 0.0, 0.0)); // Add a couple rings // Add rings - for (int i = 0; i < 20; i++) { - m_positions = AddRing(m_positions); + for (int i = 0; i < 20; i++) + { + m_positions = AddRing(m_positions); } // Set the iterator m_next = m_positions.begin(); - } +} - HexGridPositionAllocator::~HexGridPositionAllocator () - { - NS_LOG_FUNCTION_NOARGS (); - } +HexGridPositionAllocator::~HexGridPositionAllocator() +{ + NS_LOG_FUNCTION_NOARGS(); +} - const double HexGridPositionAllocator::pi = std::acos(-1); +const double HexGridPositionAllocator::pi = std::acos(-1); - double - HexGridPositionAllocator::GetRadius (void) - { +double +HexGridPositionAllocator::GetRadius(void) +{ return m_radius; - } +} - void - HexGridPositionAllocator::SetRadius (double radius) - { +void +HexGridPositionAllocator::SetRadius(double radius) +{ m_radius = radius; - } +} - Vector - HexGridPositionAllocator::GetNext (void) const - { +Vector +HexGridPositionAllocator::GetNext(void) const +{ // TODO: Check that there is a next element Vector position = *m_next; m_next++; return position; - } +} - int64_t - HexGridPositionAllocator::AssignStreams (int64_t stream) - { +int64_t +HexGridPositionAllocator::AssignStreams(int64_t stream) +{ return 0; - } +} - std::vector - HexGridPositionAllocator::AddRing (std::vector positions) - { - NS_LOG_FUNCTION (this); +std::vector +HexGridPositionAllocator::AddRing(std::vector positions) +{ + NS_LOG_FUNCTION(this); // Make a copy of the vector std::vector copy = positions; // Iterate on the given vector - for (std::vector::iterator it = positions.begin (); - it != positions.end (); it++) - { + for (std::vector::iterator it = positions.begin(); it != positions.end(); it++) + { // Get the current position Vector currentPosition = *it; - NS_LOG_DEBUG ("Current position " << currentPosition); + NS_LOG_DEBUG("Current position " << currentPosition); // Iterate to create the 6 surrounding positions // The angle is with respect to a vertical line Vector newPosition; - for (double angle = 0; angle < 2*pi; angle+=pi/3) - { - newPosition = Vector (currentPosition.x+2*m_radius*std::sin(angle), - currentPosition.y+2*m_radius*std::cos(angle), - currentPosition.z); - NS_LOG_DEBUG ("New position: " << newPosition); + for (double angle = 0; angle < 2 * pi; angle += pi / 3) + { + newPosition = Vector(currentPosition.x + 2 * m_radius * std::sin(angle), + currentPosition.y + 2 * m_radius * std::cos(angle), + currentPosition.z); + NS_LOG_DEBUG("New position: " << newPosition); // If the newly created position is not already in the copy, add it bool found = false; - for (std::vector::iterator it = copy.begin (); - it != copy.end (); it++) - { + for (std::vector::iterator it = copy.begin(); it != copy.end(); it++) + { // If the vector is already in the vector // 1 is an EPSILON used to determine whether two floats are equal if (CalculateDistance(newPosition, *it) < 10) - { + { found = true; break; - } - } + } + } if (found == false) - { - NS_LOG_DEBUG ("Adding position " << newPosition); - copy.push_back (newPosition); - } - } - } + { + NS_LOG_DEBUG("Adding position " << newPosition); + copy.push_back(newPosition); + } + } + } return copy; - } +} } // namespace ns3 diff --git a/model/hex-grid-position-allocator.h b/model/hex-grid-position-allocator.h index d2767e103b..9717434b8d 100644 --- a/model/hex-grid-position-allocator.h +++ b/model/hex-grid-position-allocator.h @@ -20,34 +20,36 @@ #define HEX_GRID_POSITION_ALLOCATOR_H #include "ns3/position-allocator.h" + #include -namespace ns3 { +namespace ns3 +{ - class HexGridPositionAllocator : public PositionAllocator - { +class HexGridPositionAllocator : public PositionAllocator +{ public: - HexGridPositionAllocator (); - HexGridPositionAllocator (double radius); + HexGridPositionAllocator(); + HexGridPositionAllocator(double radius); - ~HexGridPositionAllocator (); + ~HexGridPositionAllocator(); - virtual Vector GetNext (void) const; + virtual Vector GetNext(void) const; - virtual int64_t AssignStreams (int64_t stream); + virtual int64_t AssignStreams(int64_t stream); - static TypeId GetTypeId (void); + static TypeId GetTypeId(void); - double GetRadius (void); + double GetRadius(void); - void SetRadius (double radius); + void SetRadius(double radius); private: /** * This method adds to the given list of positions an outer ring of positions * \param position the list of position around which to create the other positions */ - std::vector AddRing (std::vector positions); + std::vector AddRing(std::vector positions); /** * The list of current positions @@ -66,7 +68,7 @@ namespace ns3 { double m_radius; const static double pi; //!< Pi - }; +}; } // namespace ns3 diff --git a/model/logical-lora-channel-helper.cc b/model/logical-lora-channel-helper.cc index 2f12606dde..080ae4b63d 100644 --- a/model/logical-lora-channel-helper.cc +++ b/model/logical-lora-channel-helper.cc @@ -18,263 +18,255 @@ * Author: Davide Magrin */ -#include "ns3/logical-lora-channel-helper.h" -#include "ns3/simulator.h" +#include "logical-lora-channel-helper.h" + #include "ns3/log.h" +#include "ns3/simulator.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LogicalLoraChannelHelper"); +NS_LOG_COMPONENT_DEFINE("LogicalLoraChannelHelper"); -NS_OBJECT_ENSURE_REGISTERED (LogicalLoraChannelHelper); +NS_OBJECT_ENSURE_REGISTERED(LogicalLoraChannelHelper); TypeId -LogicalLoraChannelHelper::GetTypeId (void) +LogicalLoraChannelHelper::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LogicalLoraChannelHelper") - .SetParent () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::LogicalLoraChannelHelper").SetParent().SetGroupName("lorawan"); + return tid; } -LogicalLoraChannelHelper::LogicalLoraChannelHelper () : - m_nextAggregatedTransmissionTime (Seconds (0)), - m_aggregatedDutyCycle (1) +LogicalLoraChannelHelper::LogicalLoraChannelHelper() + : m_nextAggregatedTransmissionTime(Seconds(0)), + m_aggregatedDutyCycle(1) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LogicalLoraChannelHelper::~LogicalLoraChannelHelper () +LogicalLoraChannelHelper::~LogicalLoraChannelHelper() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -std::vector > -LogicalLoraChannelHelper::GetChannelList (void) +std::vector> +LogicalLoraChannelHelper::GetChannelList(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Make a copy of the channel vector - std::vector > vector; - vector.reserve (m_channelList.size ()); - std::copy (m_channelList.begin (), m_channelList.end (), std::back_inserter - (vector)); + // Make a copy of the channel vector + std::vector> vector; + vector.reserve(m_channelList.size()); + std::copy(m_channelList.begin(), m_channelList.end(), std::back_inserter(vector)); - return vector; + return vector; } - -std::vector > -LogicalLoraChannelHelper::GetEnabledChannelList (void) +std::vector> +LogicalLoraChannelHelper::GetEnabledChannelList(void) { - NS_LOG_FUNCTION (this); - - // Make a copy of the channel vector - std::vector > vector; - vector.reserve (m_channelList.size ()); - std::copy (m_channelList.begin (), m_channelList.end (), std::back_inserter - (vector)); // Working on a copy - - std::vector > channels; - std::vector >::iterator it; - for (it = vector.begin (); it != vector.end (); it++) + NS_LOG_FUNCTION(this); + + // Make a copy of the channel vector + std::vector> vector; + vector.reserve(m_channelList.size()); + std::copy(m_channelList.begin(), + m_channelList.end(), + std::back_inserter(vector)); // Working on a copy + + std::vector> channels; + std::vector>::iterator it; + for (it = vector.begin(); it != vector.end(); it++) { - if ((*it)->IsEnabledForUplink ()) + if ((*it)->IsEnabledForUplink()) { - channels.push_back (*it); + channels.push_back(*it); } } - return channels; + return channels; } Ptr -LogicalLoraChannelHelper::GetSubBandFromChannel (Ptr - channel) +LogicalLoraChannelHelper::GetSubBandFromChannel(Ptr channel) { - return GetSubBandFromFrequency (channel->GetFrequency ()); + return GetSubBandFromFrequency(channel->GetFrequency()); } Ptr -LogicalLoraChannelHelper::GetSubBandFromFrequency (double frequency) +LogicalLoraChannelHelper::GetSubBandFromFrequency(double frequency) { - // Get the SubBand this frequency belongs to - std::list< Ptr< SubBand > >::iterator it; - for (it = m_subBandList.begin (); it != m_subBandList.end (); it++) + // Get the SubBand this frequency belongs to + std::list>::iterator it; + for (it = m_subBandList.begin(); it != m_subBandList.end(); it++) { - if ((*it)->BelongsToSubBand (frequency)) + if ((*it)->BelongsToSubBand(frequency)) { - return *it; + return *it; } } - NS_LOG_ERROR ("Requested frequency: " << frequency); - NS_ABORT_MSG ("Warning: frequency is outside any known SubBand."); + NS_LOG_ERROR("Requested frequency: " << frequency); + NS_ABORT_MSG("Warning: frequency is outside any known SubBand."); - return 0; // If no SubBand is found, return 0 + return 0; // If no SubBand is found, return 0 } void -LogicalLoraChannelHelper::AddChannel (double frequency) +LogicalLoraChannelHelper::AddChannel(double frequency) { - NS_LOG_FUNCTION (this << frequency); + NS_LOG_FUNCTION(this << frequency); - // Create the new channel and increment the counter - Ptr channel = Create (frequency); + // Create the new channel and increment the counter + Ptr channel = Create(frequency); - // Add it to the list - m_channelList.push_back (channel); + // Add it to the list + m_channelList.push_back(channel); - NS_LOG_DEBUG ("Added a channel. Current number of channels in list is " << - m_channelList.size ()); + NS_LOG_DEBUG("Added a channel. Current number of channels in list is " << m_channelList.size()); } void -LogicalLoraChannelHelper::AddChannel (Ptr logicalChannel) +LogicalLoraChannelHelper::AddChannel(Ptr logicalChannel) { - NS_LOG_FUNCTION (this << logicalChannel); + NS_LOG_FUNCTION(this << logicalChannel); - // Add it to the list - m_channelList.push_back (logicalChannel); + // Add it to the list + m_channelList.push_back(logicalChannel); } void -LogicalLoraChannelHelper::SetChannel (uint8_t chIndex, - Ptr logicalChannel) +LogicalLoraChannelHelper::SetChannel(uint8_t chIndex, Ptr logicalChannel) { - NS_LOG_FUNCTION (this << chIndex << logicalChannel); + NS_LOG_FUNCTION(this << chIndex << logicalChannel); - m_channelList.at (chIndex) = logicalChannel; + m_channelList.at(chIndex) = logicalChannel; } void -LogicalLoraChannelHelper::AddSubBand (double firstFrequency, - double lastFrequency, double dutyCycle, - double maxTxPowerDbm) +LogicalLoraChannelHelper::AddSubBand(double firstFrequency, + double lastFrequency, + double dutyCycle, + double maxTxPowerDbm) { - NS_LOG_FUNCTION (this << firstFrequency << lastFrequency); + NS_LOG_FUNCTION(this << firstFrequency << lastFrequency); - Ptr subBand = Create (firstFrequency, lastFrequency, - dutyCycle, maxTxPowerDbm); + Ptr subBand = Create(firstFrequency, lastFrequency, dutyCycle, maxTxPowerDbm); - m_subBandList.push_back (subBand); + m_subBandList.push_back(subBand); } void -LogicalLoraChannelHelper::AddSubBand (Ptr subBand) +LogicalLoraChannelHelper::AddSubBand(Ptr subBand) { - NS_LOG_FUNCTION (this << subBand); + NS_LOG_FUNCTION(this << subBand); - m_subBandList.push_back (subBand); + m_subBandList.push_back(subBand); } void -LogicalLoraChannelHelper::RemoveChannel (Ptr logicalChannel) +LogicalLoraChannelHelper::RemoveChannel(Ptr logicalChannel) { - // Search and remove the channel from the list - std::vector >::iterator it; - for (it = m_channelList.begin (); it != m_channelList.end (); it++) + // Search and remove the channel from the list + std::vector>::iterator it; + for (it = m_channelList.begin(); it != m_channelList.end(); it++) { - Ptr currentChannel = *it; - if (currentChannel == logicalChannel) + Ptr currentChannel = *it; + if (currentChannel == logicalChannel) { - m_channelList.erase (it); - return; + m_channelList.erase(it); + return; } } } Time -LogicalLoraChannelHelper::GetAggregatedWaitingTime (void) +LogicalLoraChannelHelper::GetAggregatedWaitingTime(void) { - // Aggregate waiting time - Time aggregatedWaitingTime = m_nextAggregatedTransmissionTime - Simulator::Now (); + // Aggregate waiting time + Time aggregatedWaitingTime = m_nextAggregatedTransmissionTime - Simulator::Now(); - // Handle case in which waiting time is negative - aggregatedWaitingTime = Seconds (std::max (aggregatedWaitingTime.GetSeconds (), - double(0))); + // Handle case in which waiting time is negative + aggregatedWaitingTime = Seconds(std::max(aggregatedWaitingTime.GetSeconds(), double(0))); - NS_LOG_DEBUG ("Aggregated waiting time: " << aggregatedWaitingTime.GetSeconds ()); + NS_LOG_DEBUG("Aggregated waiting time: " << aggregatedWaitingTime.GetSeconds()); - return aggregatedWaitingTime; + return aggregatedWaitingTime; } Time -LogicalLoraChannelHelper::GetWaitingTime (Ptr channel) +LogicalLoraChannelHelper::GetWaitingTime(Ptr channel) { - NS_LOG_FUNCTION (this << channel); + NS_LOG_FUNCTION(this << channel); - // SubBand waiting time - Time subBandWaitingTime = GetSubBandFromChannel (channel)-> - GetNextTransmissionTime () - - Simulator::Now (); + // SubBand waiting time + Time subBandWaitingTime = + GetSubBandFromChannel(channel)->GetNextTransmissionTime() - Simulator::Now(); - // Handle case in which waiting time is negative - subBandWaitingTime = Seconds (std::max (subBandWaitingTime.GetSeconds (), - double(0))); + // Handle case in which waiting time is negative + subBandWaitingTime = Seconds(std::max(subBandWaitingTime.GetSeconds(), double(0))); - NS_LOG_DEBUG ("Waiting time: " << subBandWaitingTime.GetSeconds ()); + NS_LOG_DEBUG("Waiting time: " << subBandWaitingTime.GetSeconds()); - return subBandWaitingTime; + return subBandWaitingTime; } void -LogicalLoraChannelHelper::AddEvent (Time duration, - Ptr channel) +LogicalLoraChannelHelper::AddEvent(Time duration, Ptr channel) { - NS_LOG_FUNCTION (this << duration << channel); + NS_LOG_FUNCTION(this << duration << channel); - Ptr subBand = GetSubBandFromChannel (channel); + Ptr subBand = GetSubBandFromChannel(channel); - double dutyCycle = subBand->GetDutyCycle (); - double timeOnAir = duration.GetSeconds (); + double dutyCycle = subBand->GetDutyCycle(); + double timeOnAir = duration.GetSeconds(); - // Computation of necessary waiting time on this sub-band - subBand->SetNextTransmissionTime (Simulator::Now () + Seconds - (timeOnAir / dutyCycle - timeOnAir)); + // Computation of necessary waiting time on this sub-band + subBand->SetNextTransmissionTime(Simulator::Now() + Seconds(timeOnAir / dutyCycle - timeOnAir)); - // Computation of necessary aggregate waiting time - m_nextAggregatedTransmissionTime = Simulator::Now () + Seconds - (timeOnAir / m_aggregatedDutyCycle - timeOnAir); + // Computation of necessary aggregate waiting time + m_nextAggregatedTransmissionTime = + Simulator::Now() + Seconds(timeOnAir / m_aggregatedDutyCycle - timeOnAir); - NS_LOG_DEBUG ("Time on air: " << timeOnAir); - NS_LOG_DEBUG ("m_aggregatedDutyCycle: " << m_aggregatedDutyCycle); - NS_LOG_DEBUG ("Current time: " << Simulator::Now ().GetSeconds ()); - NS_LOG_DEBUG ("Next transmission on this sub-band allowed at time: " << - (subBand->GetNextTransmissionTime ()).GetSeconds ()); - NS_LOG_DEBUG ("Next aggregated transmission allowed at time " << - m_nextAggregatedTransmissionTime.GetSeconds ()); + NS_LOG_DEBUG("Time on air: " << timeOnAir); + NS_LOG_DEBUG("m_aggregatedDutyCycle: " << m_aggregatedDutyCycle); + NS_LOG_DEBUG("Current time: " << Simulator::Now().GetSeconds()); + NS_LOG_DEBUG("Next transmission on this sub-band allowed at time: " + << (subBand->GetNextTransmissionTime()).GetSeconds()); + NS_LOG_DEBUG("Next aggregated transmission allowed at time " + << m_nextAggregatedTransmissionTime.GetSeconds()); } double -LogicalLoraChannelHelper::GetTxPowerForChannel (Ptr - logicalChannel) +LogicalLoraChannelHelper::GetTxPowerForChannel(Ptr logicalChannel) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Get the maxTxPowerDbm from the SubBand this channel is in - std::list< Ptr< SubBand > >::iterator it; - for (it = m_subBandList.begin (); it != m_subBandList.end (); it++) + // Get the maxTxPowerDbm from the SubBand this channel is in + std::list>::iterator it; + for (it = m_subBandList.begin(); it != m_subBandList.end(); it++) { - // Check whether this channel is in this SubBand - if ((*it)->BelongsToSubBand (logicalChannel->GetFrequency ())) + // Check whether this channel is in this SubBand + if ((*it)->BelongsToSubBand(logicalChannel->GetFrequency())) { - return (*it)->GetMaxTxPowerDbm (); + return (*it)->GetMaxTxPowerDbm(); } } - NS_ABORT_MSG ("Logical channel doesn't belong to a known SubBand"); + NS_ABORT_MSG("Logical channel doesn't belong to a known SubBand"); - return 0; + return 0; } void -LogicalLoraChannelHelper::DisableChannel (int index) +LogicalLoraChannelHelper::DisableChannel(int index) { - NS_LOG_FUNCTION (this << index); + NS_LOG_FUNCTION(this << index); - m_channelList.at (index)->DisableForUplink (); -} -} + m_channelList.at(index)->DisableForUplink(); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/logical-lora-channel-helper.h b/model/logical-lora-channel-helper.h index 9590fed28f..2d83cc5f30 100644 --- a/model/logical-lora-channel-helper.h +++ b/model/logical-lora-channel-helper.h @@ -21,17 +21,21 @@ #ifndef LOGICAL_LORA_CHANNEL_HELPER_H #define LOGICAL_LORA_CHANNEL_HELPER_H -#include "ns3/object.h" -#include "ns3/logical-lora-channel.h" +#include "logical-lora-channel.h" +#include "sub-band.h" + #include "ns3/nstime.h" +#include "ns3/object.h" #include "ns3/packet.h" -#include "ns3/sub-band.h" -#include + #include +#include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class supports LorawanMac instances by managing a list of the logical @@ -44,161 +48,163 @@ namespace lorawan { */ class LogicalLoraChannelHelper : public Object { -public: - static TypeId GetTypeId (void); - - LogicalLoraChannelHelper (); - virtual ~LogicalLoraChannelHelper (); - - /** - * Get the time it is necessary to wait before transmitting again, according - * to the aggregate duty cycle timer. - * - * \return The aggregate waiting time. - */ - Time GetAggregatedWaitingTime (void); - - /** - * Get the time it is necessary to wait for before transmitting on a given - * channel. - * - * \remark This function does not take into account aggregate waiting time. - * Check on this should be performed before calling this function. - * - * \param channel A pointer to the channel we want to know the waiting time - * for. - * \return A Time instance containing the waiting time before transmission is - * allowed on the channel. - */ - Time GetWaitingTime (Ptr channel); - - /** - * Register the transmission of a packet. - * - * \param duration The duration of the transmission event. - * \param channel The channel the transmission was made on. - */ - void AddEvent (Time duration, Ptr channel); - - /** - * Get the list of LogicalLoraChannels currently registered on this helper. - * - * \return A list of the managed channels. - */ - std::vector > GetChannelList (void); - - /** - * Get the list of LogicalLoraChannels currently registered on this helper - * that have been enabled for Uplink transmission with the channel mask. - * - * \return A list of the managed channels enabled for Uplink transmission. - */ - std::vector > GetEnabledChannelList (void); - - /** - * Add a new channel to the list. - * - * \param frequency The frequency of the channel to create. - */ - void AddChannel (double frequency); - - /** - * Add a new channel to the list. - * - * \param logicalChannel A pointer to the channel to add to the list. - */ - void AddChannel (Ptr logicalChannel); - - /** - * Set a new channel at a fixed index. - * - * \param chIndex The index of the channel to substitute. - * \param logicalChannel A pointer to the channel to add to the list. - */ - void SetChannel (uint8_t chIndex, Ptr logicalChannel); - - /** - * Add a new SubBand to this helper. - * - * \param firstFrequency The first frequency of the subband, in MHz. - * \param lastFrequency The last frequency of the subband, in MHz. - * \param dutyCycle The duty cycle that needs to be enforced on this subband. - * \param maxTxPowerDbm The maximum transmission power [dBm] that can be used - * on this SubBand. - */ - void AddSubBand (double firstFrequency, double lastFrequency, - double dutyCycle, double maxTxPowerDbm); - - /** - * Add a new SubBand. - * - * \param subBand A pointer to the SubBand that needs to be added. - */ - void AddSubBand (Ptr subBand); - - /** - * Remove a channel. - * - * \param channel A pointer to the channel we want to remove. - */ - void RemoveChannel (Ptr channel); - - /** - * Returns the maximum transmission power [dBm] that is allowed on a channel. - * - * \param logicalChannel The power for which to check the maximum allowed - * transmission power. - * \return The power in dBm. - */ - double GetTxPowerForChannel (Ptr logicalChannel); - - /** - * Get the SubBand a channel belongs to. - * - * \param channel The channel whose SubBand we want to get. - * \return The SubBand the channel belongs to. - */ - Ptr GetSubBandFromChannel (Ptr channel); - - /** - * Get the SubBand a frequency belongs to. - * - * \param frequency The frequency we want to check. - * \return The SubBand the frequency belongs to. - */ - Ptr GetSubBandFromFrequency (double frequency); - - /** - * Disable the channel at a specified index. - * - * \param index The index of the channel to disable. - */ - void DisableChannel (int index); - -private: - /** - * A list of the SubBands that are currently registered within this helper. - */ - std::list > m_subBandList; - - /** - * A vector of the LogicalLoraChannels that are currently registered within - * this helper. This vector represents the node's channel mask. The first N - * channels are the default ones for a fixed region. - */ - std::vector > m_channelList; - - Time m_nextAggregatedTransmissionTime; //!< The next time at which - //!transmission will be possible - //!according to the aggregated - //!transmission timer - - double m_aggregatedDutyCycle; //!< The next time at which - //!transmission will be possible - //!according to the aggregated - //!transmission timer + public: + static TypeId GetTypeId(void); + + LogicalLoraChannelHelper(); + virtual ~LogicalLoraChannelHelper(); + + /** + * Get the time it is necessary to wait before transmitting again, according + * to the aggregate duty cycle timer. + * + * \return The aggregate waiting time. + */ + Time GetAggregatedWaitingTime(void); + + /** + * Get the time it is necessary to wait for before transmitting on a given + * channel. + * + * \remark This function does not take into account aggregate waiting time. + * Check on this should be performed before calling this function. + * + * \param channel A pointer to the channel we want to know the waiting time + * for. + * \return A Time instance containing the waiting time before transmission is + * allowed on the channel. + */ + Time GetWaitingTime(Ptr channel); + + /** + * Register the transmission of a packet. + * + * \param duration The duration of the transmission event. + * \param channel The channel the transmission was made on. + */ + void AddEvent(Time duration, Ptr channel); + + /** + * Get the list of LogicalLoraChannels currently registered on this helper. + * + * \return A list of the managed channels. + */ + std::vector> GetChannelList(void); + + /** + * Get the list of LogicalLoraChannels currently registered on this helper + * that have been enabled for Uplink transmission with the channel mask. + * + * \return A list of the managed channels enabled for Uplink transmission. + */ + std::vector> GetEnabledChannelList(void); + + /** + * Add a new channel to the list. + * + * \param frequency The frequency of the channel to create. + */ + void AddChannel(double frequency); + + /** + * Add a new channel to the list. + * + * \param logicalChannel A pointer to the channel to add to the list. + */ + void AddChannel(Ptr logicalChannel); + + /** + * Set a new channel at a fixed index. + * + * \param chIndex The index of the channel to substitute. + * \param logicalChannel A pointer to the channel to add to the list. + */ + void SetChannel(uint8_t chIndex, Ptr logicalChannel); + + /** + * Add a new SubBand to this helper. + * + * \param firstFrequency The first frequency of the subband, in MHz. + * \param lastFrequency The last frequency of the subband, in MHz. + * \param dutyCycle The duty cycle that needs to be enforced on this subband. + * \param maxTxPowerDbm The maximum transmission power [dBm] that can be used + * on this SubBand. + */ + void AddSubBand(double firstFrequency, + double lastFrequency, + double dutyCycle, + double maxTxPowerDbm); + + /** + * Add a new SubBand. + * + * \param subBand A pointer to the SubBand that needs to be added. + */ + void AddSubBand(Ptr subBand); + + /** + * Remove a channel. + * + * \param channel A pointer to the channel we want to remove. + */ + void RemoveChannel(Ptr channel); + + /** + * Returns the maximum transmission power [dBm] that is allowed on a channel. + * + * \param logicalChannel The power for which to check the maximum allowed + * transmission power. + * \return The power in dBm. + */ + double GetTxPowerForChannel(Ptr logicalChannel); + + /** + * Get the SubBand a channel belongs to. + * + * \param channel The channel whose SubBand we want to get. + * \return The SubBand the channel belongs to. + */ + Ptr GetSubBandFromChannel(Ptr channel); + + /** + * Get the SubBand a frequency belongs to. + * + * \param frequency The frequency we want to check. + * \return The SubBand the frequency belongs to. + */ + Ptr GetSubBandFromFrequency(double frequency); + + /** + * Disable the channel at a specified index. + * + * \param index The index of the channel to disable. + */ + void DisableChannel(int index); + + private: + /** + * A list of the SubBands that are currently registered within this helper. + */ + std::list> m_subBandList; + + /** + * A vector of the LogicalLoraChannels that are currently registered within + * this helper. This vector represents the node's channel mask. The first N + * channels are the default ones for a fixed region. + */ + std::vector> m_channelList; + + Time m_nextAggregatedTransmissionTime; //!< The next time at which + //! transmission will be possible + //! according to the aggregated + //! transmission timer + + double m_aggregatedDutyCycle; //!< The next time at which + //! transmission will be possible + //! according to the aggregated + //! transmission timer }; -} +} // namespace lorawan -} +} // namespace ns3 #endif /* LOGICAL_LORA_CHANNEL_HELPER_H */ diff --git a/model/logical-lora-channel.cc b/model/logical-lora-channel.cc index 1912cecaac..1e2cbacdfd 100644 --- a/model/logical-lora-channel.cc +++ b/model/logical-lora-channel.cc @@ -18,123 +18,122 @@ * Author: Davide Magrin */ -#include "ns3/logical-lora-channel.h" +#include "logical-lora-channel.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LogicalLoraChannel"); +NS_LOG_COMPONENT_DEFINE("LogicalLoraChannel"); -NS_OBJECT_ENSURE_REGISTERED (LogicalLoraChannel); +NS_OBJECT_ENSURE_REGISTERED(LogicalLoraChannel); TypeId -LogicalLoraChannel::GetTypeId (void) +LogicalLoraChannel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LogicalLoraChannel") - .SetParent () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::LogicalLoraChannel").SetParent().SetGroupName("lorawan"); + return tid; } -LogicalLoraChannel::LogicalLoraChannel () : - m_frequency (0), - m_minDataRate (0), - m_maxDataRate (5), - m_enabledForUplink (true) +LogicalLoraChannel::LogicalLoraChannel() + : m_frequency(0), + m_minDataRate(0), + m_maxDataRate(5), + m_enabledForUplink(true) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LogicalLoraChannel::~LogicalLoraChannel () +LogicalLoraChannel::~LogicalLoraChannel() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LogicalLoraChannel::LogicalLoraChannel (double frequency) : - m_frequency (frequency), - m_enabledForUplink (true) +LogicalLoraChannel::LogicalLoraChannel(double frequency) + : m_frequency(frequency), + m_enabledForUplink(true) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LogicalLoraChannel::LogicalLoraChannel (double frequency, uint8_t minDataRate, - uint8_t maxDataRate) : - m_frequency (frequency), - m_minDataRate (minDataRate), - m_maxDataRate (maxDataRate), - m_enabledForUplink (true) +LogicalLoraChannel::LogicalLoraChannel(double frequency, uint8_t minDataRate, uint8_t maxDataRate) + : m_frequency(frequency), + m_minDataRate(minDataRate), + m_maxDataRate(maxDataRate), + m_enabledForUplink(true) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } double -LogicalLoraChannel::GetFrequency (void) const +LogicalLoraChannel::GetFrequency(void) const { - return m_frequency; + return m_frequency; } void -LogicalLoraChannel::SetMinimumDataRate (uint8_t minDataRate) +LogicalLoraChannel::SetMinimumDataRate(uint8_t minDataRate) { - m_minDataRate = minDataRate; + m_minDataRate = minDataRate; } void -LogicalLoraChannel::SetMaximumDataRate (uint8_t maxDataRate) +LogicalLoraChannel::SetMaximumDataRate(uint8_t maxDataRate) { - m_maxDataRate = maxDataRate; + m_maxDataRate = maxDataRate; } uint8_t -LogicalLoraChannel::GetMinimumDataRate (void) +LogicalLoraChannel::GetMinimumDataRate(void) { - return m_minDataRate; + return m_minDataRate; } uint8_t -LogicalLoraChannel::GetMaximumDataRate (void) +LogicalLoraChannel::GetMaximumDataRate(void) { - return m_maxDataRate; + return m_maxDataRate; } void -LogicalLoraChannel::SetEnabledForUplink (void) +LogicalLoraChannel::SetEnabledForUplink(void) { - m_enabledForUplink = true; + m_enabledForUplink = true; } void -LogicalLoraChannel::DisableForUplink (void) +LogicalLoraChannel::DisableForUplink(void) { - m_enabledForUplink = false; + m_enabledForUplink = false; } bool -LogicalLoraChannel::IsEnabledForUplink (void) +LogicalLoraChannel::IsEnabledForUplink(void) { - return m_enabledForUplink; + return m_enabledForUplink; } bool -operator== (const Ptr& first, - const Ptr& second) +operator==(const Ptr& first, const Ptr& second) { - double thisFreq = first->GetFrequency (); - double otherFreq = second->GetFrequency (); + double thisFreq = first->GetFrequency(); + double otherFreq = second->GetFrequency(); - NS_LOG_DEBUG ("Checking equality between logical lora channels: " << - thisFreq << " " << otherFreq); + NS_LOG_DEBUG("Checking equality between logical lora channels: " << thisFreq << " " + << otherFreq); - NS_LOG_DEBUG ("Result:" << (thisFreq == otherFreq)); - return (thisFreq == otherFreq); + NS_LOG_DEBUG("Result:" << (thisFreq == otherFreq)); + return (thisFreq == otherFreq); } bool -operator!= (const Ptr& first, - const Ptr& second) +operator!=(const Ptr& first, const Ptr& second) { - return !(first == second); -} -} + return !(first == second); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/logical-lora-channel.h b/model/logical-lora-channel.h index e85697a4ec..0bb47deed4 100644 --- a/model/logical-lora-channel.h +++ b/model/logical-lora-channel.h @@ -21,11 +21,14 @@ #ifndef LOGICAL_LORA_CHANNEL_H #define LOGICAL_LORA_CHANNEL_H +#include "sub-band.h" + #include "ns3/object.h" -#include "ns3/sub-band.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class SubBand; @@ -40,106 +43,105 @@ class SubBand; */ class LogicalLoraChannel : public Object { -public: - static TypeId GetTypeId (void); - - LogicalLoraChannel (); - virtual ~LogicalLoraChannel (); - - LogicalLoraChannel (double frequency); - - /** - * Constructor providing initialization of frequency and data rate limits. - * - * \param frequency This channel's frequency. - * \param minDataRate This channel's minimum data rate. - * \param maxDataRate This channel's maximum data rate. - */ - LogicalLoraChannel (double frequency, uint8_t minDataRate, - uint8_t maxDataRate); - - /** - * Get the frequency (MHz). - * - * \return The center frequency of this channel. - */ - double GetFrequency (void) const; - - /** - * Set the frequency (MHz). - * - * \param frequencyMHz The center frequency this channel should be at. - */ - // void SetFrequency (double frequencyMHz); - - /** - * Set the minimum Data Rate that is allowed on this channel. - */ - void SetMinimumDataRate (uint8_t minDataRate); - - /** - * Set the maximum Data Rate that is allowed on this channel. - */ - void SetMaximumDataRate (uint8_t maxDataRate); - - /** - * Get the minimum Data Rate that is allowed on this channel. - */ - uint8_t GetMinimumDataRate (void); - - /** - * Get the maximum Data Rate that is allowed on this channel. - */ - uint8_t GetMaximumDataRate (void); - - /** - * Set this channel as enabled for uplink. - */ - void SetEnabledForUplink (void); - - /** - * Set this channel as disabled for uplink. - */ - void DisableForUplink (void); - - /** - * Test whether this channel is marked as enabled for uplink. - */ - bool IsEnabledForUplink (void); - -private: - /** - * The central frequency of this channel, in MHz. - */ - double m_frequency; - - /** - * The minimum Data Rate that is allowed on this channel. - */ - uint8_t m_minDataRate; - - /** - * The maximum Data Rate that is allowed on this channel. - */ - uint8_t m_maxDataRate; - - /** - * Whether this channel can be used for uplink or not. - */ - bool m_enabledForUplink; + public: + static TypeId GetTypeId(void); + + LogicalLoraChannel(); + virtual ~LogicalLoraChannel(); + + LogicalLoraChannel(double frequency); + + /** + * Constructor providing initialization of frequency and data rate limits. + * + * \param frequency This channel's frequency. + * \param minDataRate This channel's minimum data rate. + * \param maxDataRate This channel's maximum data rate. + */ + LogicalLoraChannel(double frequency, uint8_t minDataRate, uint8_t maxDataRate); + + /** + * Get the frequency (MHz). + * + * \return The center frequency of this channel. + */ + double GetFrequency(void) const; + + /** + * Set the frequency (MHz). + * + * \param frequencyMHz The center frequency this channel should be at. + */ + // void SetFrequency (double frequencyMHz); + + /** + * Set the minimum Data Rate that is allowed on this channel. + */ + void SetMinimumDataRate(uint8_t minDataRate); + + /** + * Set the maximum Data Rate that is allowed on this channel. + */ + void SetMaximumDataRate(uint8_t maxDataRate); + + /** + * Get the minimum Data Rate that is allowed on this channel. + */ + uint8_t GetMinimumDataRate(void); + + /** + * Get the maximum Data Rate that is allowed on this channel. + */ + uint8_t GetMaximumDataRate(void); + + /** + * Set this channel as enabled for uplink. + */ + void SetEnabledForUplink(void); + + /** + * Set this channel as disabled for uplink. + */ + void DisableForUplink(void); + + /** + * Test whether this channel is marked as enabled for uplink. + */ + bool IsEnabledForUplink(void); + + private: + /** + * The central frequency of this channel, in MHz. + */ + double m_frequency; + + /** + * The minimum Data Rate that is allowed on this channel. + */ + uint8_t m_minDataRate; + + /** + * The maximum Data Rate that is allowed on this channel. + */ + uint8_t m_maxDataRate; + + /** + * Whether this channel can be used for uplink or not. + */ + bool m_enabledForUplink; }; /** * Overload of the == operator to compare different instances of the same LogicalLoraChannel */ -bool operator== (const Ptr& first, const Ptr& second); +bool operator==(const Ptr& first, const Ptr& second); /** * Overload the != operator to compare different instances of the same LogicalLoraChannel */ -bool operator!= (const Ptr& first, const Ptr& second); +bool operator!=(const Ptr& first, const Ptr& second); -} +} // namespace lorawan -} +} // namespace ns3 #endif /* LOGICAL_LORA_CHANNEL_H */ diff --git a/model/lora-channel.cc b/model/lora-channel.cc index 54e01256b5..5446f72b19 100644 --- a/model/lora-channel.cc +++ b/model/lora-channel.cc @@ -18,192 +18,205 @@ * Author: Davide Magrin */ -#include "ns3/lora-channel.h" +#include "lora-channel.h" + +#include "end-device-lora-phy.h" +#include "gateway-lora-phy.h" + #include "ns3/log.h" -#include "ns3/pointer.h" #include "ns3/object-factory.h" #include "ns3/packet.h" +#include "ns3/pointer.h" #include "ns3/simulator.h" -#include "ns3/end-device-lora-phy.h" -#include "ns3/gateway-lora-phy.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraChannel"); +NS_LOG_COMPONENT_DEFINE("LoraChannel"); -NS_OBJECT_ENSURE_REGISTERED (LoraChannel); +NS_OBJECT_ENSURE_REGISTERED(LoraChannel); TypeId -LoraChannel::GetTypeId (void) +LoraChannel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LoraChannel") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor () - .AddAttribute ("PropagationLossModel", - "A pointer to the propagation loss model attached to this channel.", - PointerValue (), - MakePointerAccessor (&LoraChannel::m_loss), - MakePointerChecker ()) - .AddAttribute ("PropagationDelayModel", - "A pointer to the propagation delay model attached to this channel.", - PointerValue (), - MakePointerAccessor (&LoraChannel::m_delay), - MakePointerChecker ()) - .AddTraceSource ("PacketSent", - "Trace source fired whenever a packet goes out on the channel", - MakeTraceSourceAccessor (&LoraChannel::m_packetSent), - "ns3::Packet::TracedCallback"); - return tid; + static TypeId tid = + TypeId("ns3::LoraChannel") + .SetParent() + .SetGroupName("lorawan") + .AddConstructor() + .AddAttribute("PropagationLossModel", + "A pointer to the propagation loss model attached to this channel.", + PointerValue(), + MakePointerAccessor(&LoraChannel::m_loss), + MakePointerChecker()) + .AddAttribute("PropagationDelayModel", + "A pointer to the propagation delay model attached to this channel.", + PointerValue(), + MakePointerAccessor(&LoraChannel::m_delay), + MakePointerChecker()) + .AddTraceSource("PacketSent", + "Trace source fired whenever a packet goes out on the channel", + MakeTraceSourceAccessor(&LoraChannel::m_packetSent), + "ns3::Packet::TracedCallback"); + return tid; } -LoraChannel::LoraChannel () +LoraChannel::LoraChannel() { } -LoraChannel::~LoraChannel () +LoraChannel::~LoraChannel() { - m_phyList.clear (); + m_phyList.clear(); } -LoraChannel::LoraChannel (Ptr loss, - Ptr delay) : - m_loss (loss), - m_delay (delay) +LoraChannel::LoraChannel(Ptr loss, Ptr delay) + : m_loss(loss), + m_delay(delay) { } void -LoraChannel::Add (Ptr phy) +LoraChannel::Add(Ptr phy) { - NS_LOG_FUNCTION (this << phy); + NS_LOG_FUNCTION(this << phy); - // Add the new phy to the vector - m_phyList.push_back (phy); + // Add the new phy to the vector + m_phyList.push_back(phy); } void -LoraChannel::Remove (Ptr phy) +LoraChannel::Remove(Ptr phy) { - NS_LOG_FUNCTION (this << phy); + NS_LOG_FUNCTION(this << phy); - // Remove the phy from the vector - m_phyList.erase (find (m_phyList.begin (), m_phyList.end (), phy)); + // Remove the phy from the vector + m_phyList.erase(find(m_phyList.begin(), m_phyList.end(), phy)); } std::size_t -LoraChannel::GetNDevices (void) const +LoraChannel::GetNDevices(void) const { - return m_phyList.size (); + return m_phyList.size(); } Ptr -LoraChannel::GetDevice (std::size_t i) const +LoraChannel::GetDevice(std::size_t i) const { - return m_phyList[i]->GetDevice ()->GetObject (); + return m_phyList[i]->GetDevice()->GetObject(); } void -LoraChannel::Send (Ptr< LoraPhy > sender, Ptr< Packet > packet, - double txPowerDbm, LoraTxParameters txParams, - Time duration, double frequencyMHz) const +LoraChannel::Send(Ptr sender, + Ptr packet, + double txPowerDbm, + LoraTxParameters txParams, + Time duration, + double frequencyMHz) const { - NS_LOG_FUNCTION (this << sender << packet << txPowerDbm << txParams << - duration << frequencyMHz); + NS_LOG_FUNCTION(this << sender << packet << txPowerDbm << txParams << duration << frequencyMHz); - // Get the mobility model of the sender - Ptr senderMobility = sender->GetMobility ()->GetObject (); + // Get the mobility model of the sender + Ptr senderMobility = sender->GetMobility()->GetObject(); - NS_ASSERT (senderMobility); // Make sure it's available + NS_ASSERT(senderMobility); // Make sure it's available - NS_LOG_INFO ("Starting cycle over all " << m_phyList.size () << " PHYs"); - NS_LOG_INFO ("Sender mobility: " << senderMobility->GetPosition ()); + NS_LOG_INFO("Starting cycle over all " << m_phyList.size() << " PHYs"); + NS_LOG_INFO("Sender mobility: " << senderMobility->GetPosition()); - // Cycle over all registered PHYs - uint32_t j = 0; - std::vector >::const_iterator i; - for (i = m_phyList.begin (); i != m_phyList.end (); i++, j++) + // Cycle over all registered PHYs + uint32_t j = 0; + std::vector>::const_iterator i; + for (i = m_phyList.begin(); i != m_phyList.end(); i++, j++) { - // Do not deliver to the sender (*i is the current PHY) - if (sender != (*i)) + // Do not deliver to the sender (*i is the current PHY) + if (sender != (*i)) { - // Get the receiver's mobility model - Ptr receiverMobility = (*i)->GetMobility ()-> - GetObject (); + // Get the receiver's mobility model + Ptr receiverMobility = (*i)->GetMobility()->GetObject(); - NS_LOG_INFO ("Receiver mobility: " << - receiverMobility->GetPosition ()); + NS_LOG_INFO("Receiver mobility: " << receiverMobility->GetPosition()); - // Compute delay using the delay model - Time delay = m_delay->GetDelay (senderMobility, receiverMobility); + // Compute delay using the delay model + Time delay = m_delay->GetDelay(senderMobility, receiverMobility); - // Compute received power using the loss model - double rxPowerDbm = GetRxPower (txPowerDbm, senderMobility, - receiverMobility); + // Compute received power using the loss model + double rxPowerDbm = GetRxPower(txPowerDbm, senderMobility, receiverMobility); - NS_LOG_DEBUG ("Propagation: txPower=" << txPowerDbm << - "dbm, rxPower=" << rxPowerDbm << "dbm, " << - "distance=" << senderMobility->GetDistanceFrom (receiverMobility) << - "m, delay=" << delay); + NS_LOG_DEBUG("Propagation: txPower=" + << txPowerDbm << "dbm, rxPower=" << rxPowerDbm << "dbm, " + << "distance=" << senderMobility->GetDistanceFrom(receiverMobility) + << "m, delay=" << delay); - // Get the id of the destination PHY to correctly format the context - Ptr dstNetDevice = m_phyList[j]->GetDevice (); - uint32_t dstNode = 0; - if (dstNetDevice) + // Get the id of the destination PHY to correctly format the context + Ptr dstNetDevice = m_phyList[j]->GetDevice(); + uint32_t dstNode = 0; + if (dstNetDevice) { - NS_LOG_INFO ("Getting node index from NetDevice, since it exists"); - dstNode = dstNetDevice->GetNode ()->GetId (); - NS_LOG_DEBUG ("dstNode = " << dstNode); + NS_LOG_INFO("Getting node index from NetDevice, since it exists"); + dstNode = dstNetDevice->GetNode()->GetId(); + NS_LOG_DEBUG("dstNode = " << dstNode); } - else + else { - NS_LOG_INFO ("No net device connected to the PHY, using context 0"); + NS_LOG_INFO("No net device connected to the PHY, using context 0"); } - // Create the parameters object based on the calculations above - LoraChannelParameters parameters; - parameters.rxPowerDbm = rxPowerDbm; - parameters.sf = txParams.sf; - parameters.duration = duration; - parameters.frequencyMHz = frequencyMHz; - - // Schedule the receive event - NS_LOG_INFO ("Scheduling reception of the packet"); - Simulator::ScheduleWithContext (dstNode, delay, &LoraChannel::Receive, - this, j, packet, parameters); - - // Fire the trace source for sent packet - m_packetSent (packet); + // Create the parameters object based on the calculations above + LoraChannelParameters parameters; + parameters.rxPowerDbm = rxPowerDbm; + parameters.sf = txParams.sf; + parameters.duration = duration; + parameters.frequencyMHz = frequencyMHz; + + // Schedule the receive event + NS_LOG_INFO("Scheduling reception of the packet"); + Simulator::ScheduleWithContext(dstNode, + delay, + &LoraChannel::Receive, + this, + j, + packet, + parameters); + + // Fire the trace source for sent packet + m_packetSent(packet); } } } void -LoraChannel::Receive (uint32_t i, Ptr packet, - LoraChannelParameters parameters) const +LoraChannel::Receive(uint32_t i, Ptr packet, LoraChannelParameters parameters) const { - NS_LOG_FUNCTION (this << i << packet << parameters); - - // Call the appropriate PHY instance to let it begin reception - m_phyList[i]->StartReceive (packet, parameters.rxPowerDbm, parameters.sf, - parameters.duration, parameters.frequencyMHz); + NS_LOG_FUNCTION(this << i << packet << parameters); + + // Call the appropriate PHY instance to let it begin reception + m_phyList[i]->StartReceive(packet, + parameters.rxPowerDbm, + parameters.sf, + parameters.duration, + parameters.frequencyMHz); } double -LoraChannel::GetRxPower (double txPowerDbm, Ptr senderMobility, - Ptr receiverMobility) const +LoraChannel::GetRxPower(double txPowerDbm, + Ptr senderMobility, + Ptr receiverMobility) const { - return m_loss->CalcRxPower (txPowerDbm, senderMobility, receiverMobility); + return m_loss->CalcRxPower(txPowerDbm, senderMobility, receiverMobility); } -std::ostream &operator << (std::ostream &os, const LoraChannelParameters ¶ms) +std::ostream& +operator<<(std::ostream& os, const LoraChannelParameters& params) { - os << "(rxPowerDbm: " << params.rxPowerDbm << ", SF: " << unsigned(params.sf) << - ", durationSec: " << params.duration.GetSeconds () << - ", frequencyMHz: " << params.frequencyMHz << ")"; - return os; -} -} + os << "(rxPowerDbm: " << params.rxPowerDbm << ", SF: " << unsigned(params.sf) + << ", durationSec: " << params.duration.GetSeconds() + << ", frequencyMHz: " << params.frequencyMHz << ")"; + return os; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-channel.h b/model/lora-channel.h index a6de5dc4de..7f9e0f3ec6 100644 --- a/model/lora-channel.h +++ b/model/lora-channel.h @@ -24,22 +24,27 @@ #ifndef LORA_CHANNEL_H #define LORA_CHANNEL_H -#include -#include "ns3/lora-phy.h" -#include "ns3/mobility-model.h" +#include "logical-lora-channel.h" +#include "lora-phy.h" + #include "ns3/channel.h" +#include "ns3/mobility-model.h" #include "ns3/net-device.h" -#include "ns3/propagation-loss-model.h" -#include "ns3/propagation-delay-model.h" -#include "ns3/logical-lora-channel.h" -#include "ns3/packet.h" #include "ns3/nstime.h" +#include "ns3/packet.h" +#include "ns3/propagation-delay-model.h" +#include "ns3/propagation-loss-model.h" + +#include -namespace ns3 { +namespace ns3 +{ class NetDevice; class PropagationLossModel; class PropagationDelayModel; -namespace lorawan { + +namespace lorawan +{ class LoraPhy; struct LoraTxParameters; @@ -50,16 +55,16 @@ struct LoraTxParameters; */ struct LoraChannelParameters { - double rxPowerDbm; //!< The reception power. - uint8_t sf; //!< The Spreading Factor of this transmission. - Time duration; //!< The duration of the transmission. - double frequencyMHz; //!< The frequency [MHz] of this transmission. + double rxPowerDbm; //!< The reception power. + uint8_t sf; //!< The Spreading Factor of this transmission. + Time duration; //!< The duration of the transmission. + double frequencyMHz; //!< The frequency [MHz] of this transmission. }; /** * Allow logging of LoraChannelParameters like with any other data type. */ -std::ostream &operator << (std::ostream &os, const LoraChannelParameters ¶ms); +std::ostream& operator<<(std::ostream& os, const LoraChannelParameters& params); /** * The class that delivers packets among PHY layers. @@ -72,129 +77,130 @@ std::ostream &operator << (std::ostream &os, const LoraChannelParameters ¶ms */ class LoraChannel : public Channel { -public: - // TypeId - static TypeId GetTypeId (void); - - // Constructor and destructor - LoraChannel (); - virtual ~LoraChannel (); - - // Inherited from Channel. - virtual std::size_t GetNDevices (void) const; - virtual Ptr GetDevice (std::size_t i) const; - - /** - * Construct a LoraChannel with a loss and delay model. - * - * \param loss The loss model to associate to this channel. - * \param delay The delay model to associate to this channel. - */ - LoraChannel (Ptr loss, - Ptr delay); - - /** - * Connect a LoraPhy object to the LoraChannel. - * - * This method is needed so that the channel knows it has to notify this PHY - * of incoming transmissions. - * - * \param phy The physical layer to add. - */ - void Add (Ptr phy); - - /** - * Remove a physical layer from the LoraChannel. - * - * This method removes a phy from the list of devices we have to notify. - * Removing unused PHY layers from the channel can improve performance, since - * it is not necessary to notify them about each transmission. - * - * \param phy The physical layer to remove. - */ - void Remove (Ptr phy); - - /** - * Send a packet in the channel. - * - * This method is typically invoked by a PHY that needs to send a packet. - * Every connected Phy will be notified of this packet send through a call to - * their StartReceive methods after a delay based on the channel's - * PropagationDelayModel. - * - * \param sender The phy that is sending this packet. - * \param packet The PHY layer packet that is being sent over the channel. - * \param txPowerDbm The power of the transmission. - * \param txParams The set of parameters that are used by the transmitter. - * \param duration The on-air duration of this packet. - * \param frequencyMHz The frequency this transmission will happen at. - * - * \internal - * - * When this method is called, the channel schedules an internal Receive call - * that performs the actual call to the PHY's StartReceive function. - */ - void Send (Ptr sender, Ptr packet, double txPowerDbm, - LoraTxParameters txParams, Time duration, double frequencyMHz) - const; - - /** - * Compute the received power when transmitting from a point to another one. - * - * This method can be used by external object to see the receive power of a - * transmission from one point to another using this Channel's - * PropagationLossModel. - * - * \param txPowerDbm The power the transmitter is using, in dBm. - * \param senderMobility The mobility model of the sender. - * \param receiverMobility The mobility model of the receiver. - * \return The received power in dBm. - */ - double GetRxPower (double txPowerDbm, Ptr senderMobility, - Ptr receiverMobility) const; - -private: - /** - * Private method that is scheduled by LoraChannel's Send method to happen - * after the channel delay, for each of the connected PHY layers. - * - * It's here that the Receive method of the PHY is called to initiate packet - * reception at the PHY. - * - * \param i The index of the phy to start reception on. - * \param packet The packet the phy will receive. - * \param parameters The parameters that characterize this transmission - */ - void Receive (uint32_t i, Ptr packet, - LoraChannelParameters parameters) const; - - /** - * The vector containing the PHYs that are currently connected to the - * channel. - */ - std::vector > m_phyList; - - /** - * Pointer to the loss model. - * - * This loss model can be a concatenation of multiple loss models, obtained - * via PropagationLossModel's SetNext method. - */ - Ptr m_loss; - - /** - * Pointer to the delay model. - */ - Ptr m_delay; - - /** - * Callback for when a packet is being sent on the channel. - */ - TracedCallback > m_packetSent; - + public: + // TypeId + static TypeId GetTypeId(void); + + // Constructor and destructor + LoraChannel(); + virtual ~LoraChannel(); + + // Inherited from Channel. + virtual std::size_t GetNDevices(void) const; + virtual Ptr GetDevice(std::size_t i) const; + + /** + * Construct a LoraChannel with a loss and delay model. + * + * \param loss The loss model to associate to this channel. + * \param delay The delay model to associate to this channel. + */ + LoraChannel(Ptr loss, Ptr delay); + + /** + * Connect a LoraPhy object to the LoraChannel. + * + * This method is needed so that the channel knows it has to notify this PHY + * of incoming transmissions. + * + * \param phy The physical layer to add. + */ + void Add(Ptr phy); + + /** + * Remove a physical layer from the LoraChannel. + * + * This method removes a phy from the list of devices we have to notify. + * Removing unused PHY layers from the channel can improve performance, since + * it is not necessary to notify them about each transmission. + * + * \param phy The physical layer to remove. + */ + void Remove(Ptr phy); + + /** + * Send a packet in the channel. + * + * This method is typically invoked by a PHY that needs to send a packet. + * Every connected Phy will be notified of this packet send through a call to + * their StartReceive methods after a delay based on the channel's + * PropagationDelayModel. + * + * \param sender The phy that is sending this packet. + * \param packet The PHY layer packet that is being sent over the channel. + * \param txPowerDbm The power of the transmission. + * \param txParams The set of parameters that are used by the transmitter. + * \param duration The on-air duration of this packet. + * \param frequencyMHz The frequency this transmission will happen at. + * + * \internal + * + * When this method is called, the channel schedules an internal Receive call + * that performs the actual call to the PHY's StartReceive function. + */ + void Send(Ptr sender, + Ptr packet, + double txPowerDbm, + LoraTxParameters txParams, + Time duration, + double frequencyMHz) const; + + /** + * Compute the received power when transmitting from a point to another one. + * + * This method can be used by external object to see the receive power of a + * transmission from one point to another using this Channel's + * PropagationLossModel. + * + * \param txPowerDbm The power the transmitter is using, in dBm. + * \param senderMobility The mobility model of the sender. + * \param receiverMobility The mobility model of the receiver. + * \return The received power in dBm. + */ + double GetRxPower(double txPowerDbm, + Ptr senderMobility, + Ptr receiverMobility) const; + + private: + /** + * Private method that is scheduled by LoraChannel's Send method to happen + * after the channel delay, for each of the connected PHY layers. + * + * It's here that the Receive method of the PHY is called to initiate packet + * reception at the PHY. + * + * \param i The index of the phy to start reception on. + * \param packet The packet the phy will receive. + * \param parameters The parameters that characterize this transmission + */ + void Receive(uint32_t i, Ptr packet, LoraChannelParameters parameters) const; + + /** + * The vector containing the PHYs that are currently connected to the + * channel. + */ + std::vector> m_phyList; + + /** + * Pointer to the loss model. + * + * This loss model can be a concatenation of multiple loss models, obtained + * via PropagationLossModel's SetNext method. + */ + Ptr m_loss; + + /** + * Pointer to the delay model. + */ + Ptr m_delay; + + /** + * Callback for when a packet is being sent on the channel. + */ + TracedCallback> m_packetSent; }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_CHANNEL_H */ diff --git a/model/lora-device-address-generator.cc b/model/lora-device-address-generator.cc index 0f61e9ef43..537a434a22 100644 --- a/model/lora-device-address-generator.cc +++ b/model/lora-device-address-generator.cc @@ -18,61 +18,63 @@ * Author: Davide Magrin */ -#include "ns3/lora-device-address-generator.h" +#include "lora-device-address-generator.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraDeviceAddressGenerator"); +NS_LOG_COMPONENT_DEFINE("LoraDeviceAddressGenerator"); TypeId -LoraDeviceAddressGenerator::GetTypeId (void) +LoraDeviceAddressGenerator::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LoraDeviceAddressGenerator") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor (); - return tid; + static TypeId tid = TypeId("ns3::LoraDeviceAddressGenerator") + .SetParent() + .SetGroupName("lorawan") + .AddConstructor(); + return tid; } -LoraDeviceAddressGenerator::LoraDeviceAddressGenerator (const uint8_t nwkId, - const uint32_t nwkAddr) +LoraDeviceAddressGenerator::LoraDeviceAddressGenerator(const uint8_t nwkId, const uint32_t nwkAddr) { - NS_LOG_FUNCTION (this << unsigned(nwkId) << nwkAddr); + NS_LOG_FUNCTION(this << unsigned(nwkId) << nwkAddr); - m_currentNwkId.Set (nwkId); - m_currentNwkAddr.Set (nwkAddr); + m_currentNwkId.Set(nwkId); + m_currentNwkAddr.Set(nwkAddr); } LoraDeviceAddress -LoraDeviceAddressGenerator::NextNetwork (void) +LoraDeviceAddressGenerator::NextNetwork(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_currentNwkId.Set (m_currentNwkId.Get () + 1); - m_currentNwkAddr.Set (0); + m_currentNwkId.Set(m_currentNwkId.Get() + 1); + m_currentNwkAddr.Set(0); - return LoraDeviceAddress (m_currentNwkId, m_currentNwkAddr); + return LoraDeviceAddress(m_currentNwkId, m_currentNwkAddr); } LoraDeviceAddress -LoraDeviceAddressGenerator::NextAddress (void) +LoraDeviceAddressGenerator::NextAddress(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - NwkAddr oldNwkAddr = m_currentNwkAddr; - m_currentNwkAddr.Set (m_currentNwkAddr.Get () + 1); + NwkAddr oldNwkAddr = m_currentNwkAddr; + m_currentNwkAddr.Set(m_currentNwkAddr.Get() + 1); - return LoraDeviceAddress (m_currentNwkId, oldNwkAddr); + return LoraDeviceAddress(m_currentNwkId, oldNwkAddr); } LoraDeviceAddress -LoraDeviceAddressGenerator::GetNextAddress (void) +LoraDeviceAddressGenerator::GetNextAddress(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return LoraDeviceAddress (m_currentNwkId.Get (), m_currentNwkAddr.Get () + 1); -} -} + return LoraDeviceAddress(m_currentNwkId.Get(), m_currentNwkAddr.Get() + 1); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-device-address-generator.h b/model/lora-device-address-generator.h index f0f21c43d2..643e3b4471 100644 --- a/model/lora-device-address-generator.h +++ b/model/lora-device-address-generator.h @@ -21,69 +21,71 @@ #ifndef LORA_DEVICE_ADDRESS_GENERATOR_H #define LORA_DEVICE_ADDRESS_GENERATOR_H -#include "ns3/lora-device-address.h" +#include "lora-device-address.h" + #include "ns3/object.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class generates sequential LoraDeviceAddress instances. */ class LoraDeviceAddressGenerator : public Object { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); - /** - * Initialise the base NwkID and the first NwkAddr to be used by the - * generator. - * - * The first call to NextAddress() or GetAddress() will return these values. - * - * \param nwkId The first network id. - * \param nwkAddr The first address. - */ - LoraDeviceAddressGenerator (const uint8_t nwkId = 0, - const uint32_t nwkAddr = 0); + /** + * Initialise the base NwkID and the first NwkAddr to be used by the + * generator. + * + * The first call to NextAddress() or GetAddress() will return these values. + * + * \param nwkId The first network id. + * \param nwkAddr The first address. + */ + LoraDeviceAddressGenerator(const uint8_t nwkId = 0, const uint32_t nwkAddr = 0); - /** - * Get the first address from the next network. - * - * This resets the address to the base address that was used for - * initialization. - * - * \return the LoraDeviceAddress address of the next network - */ - LoraDeviceAddress NextNetwork (void); + /** + * Get the first address from the next network. + * + * This resets the address to the base address that was used for + * initialization. + * + * \return the LoraDeviceAddress address of the next network + */ + LoraDeviceAddress NextNetwork(void); - /** - * Allocate the next LoraDeviceAddress. - * - * This operation is a post-increment, meaning that the first address - * allocated will be the one that was initially configured. - * - * This keeps the nwkId constant, only incrementing nwkAddr. - * - * \return the LoraDeviceAddress address - */ - LoraDeviceAddress NextAddress (void); + /** + * Allocate the next LoraDeviceAddress. + * + * This operation is a post-increment, meaning that the first address + * allocated will be the one that was initially configured. + * + * This keeps the nwkId constant, only incrementing nwkAddr. + * + * \return the LoraDeviceAddress address + */ + LoraDeviceAddress NextAddress(void); - /** - * Get the LoraDeviceAddress that will be allocated upon a call to - * NextAddress. - * - * Does not change the internal state; is just used to peek at the next - * address that will be allocated upon a call to NextAddress - * - * \return the LoraDeviceAddress - */ - LoraDeviceAddress GetNextAddress (void); + /** + * Get the LoraDeviceAddress that will be allocated upon a call to + * NextAddress. + * + * Does not change the internal state; is just used to peek at the next + * address that will be allocated upon a call to NextAddress + * + * \return the LoraDeviceAddress + */ + LoraDeviceAddress GetNextAddress(void); -private: - NwkID m_currentNwkId; //!< The current Network Id value - NwkAddr m_currentNwkAddr; //!< The current Network Address value + private: + NwkID m_currentNwkId; //!< The current Network Id value + NwkAddr m_currentNwkAddr; //!< The current Network Address value }; -} //namespace ns3 -} +} // namespace lorawan +} // namespace ns3 #endif diff --git a/model/lora-device-address.cc b/model/lora-device-address.cc index dc17281375..f20ff4e37c 100644 --- a/model/lora-device-address.cc +++ b/model/lora-device-address.cc @@ -18,253 +18,262 @@ * Author: Davide Magrin */ -#include "ns3/lora-device-address.h" +#include "lora-device-address.h" + #include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraDeviceAddress"); +NS_LOG_COMPONENT_DEFINE("LoraDeviceAddress"); // NwkID //////// -NwkID::NwkID (uint8_t nwkId) : m_nwkId (nwkId) +NwkID::NwkID(uint8_t nwkId) + : m_nwkId(nwkId) { } void -NwkID::Set (uint8_t nwkId) +NwkID::Set(uint8_t nwkId) { - // Check whether the MSB is set - if (nwkId >> 7) + // Check whether the MSB is set + if (nwkId >> 7) { - NS_LOG_WARN ("Attempting to set too big a network ID. Will only consider the 7 least significant bits."); + NS_LOG_WARN("Attempting to set too big a network ID. Will only consider the 7 least " + "significant bits."); } - m_nwkId = nwkId & 0x7F; // 0x7f = ob01111111 + m_nwkId = nwkId & 0x7F; // 0x7f = ob01111111 } uint8_t -NwkID::Get (void) const +NwkID::Get(void) const { - return m_nwkId; + return m_nwkId; } // NwkAddr ////////// -NwkAddr::NwkAddr (uint32_t nwkAddr) : m_nwkAddr (nwkAddr) +NwkAddr::NwkAddr(uint32_t nwkAddr) + : m_nwkAddr(nwkAddr) { } void -NwkAddr::Set (uint32_t nwkAddr) +NwkAddr::Set(uint32_t nwkAddr) { - // Check whether the most significant bits are set - if (nwkAddr >> 25) + // Check whether the most significant bits are set + if (nwkAddr >> 25) { - NS_LOG_WARN ("Attempting to set too big a network address. Will only consider the 25 least significant bits."); + NS_LOG_WARN("Attempting to set too big a network address. Will only consider the 25 least " + "significant bits."); } - m_nwkAddr = nwkAddr & 0x1FFFFFF; + m_nwkAddr = nwkAddr & 0x1FFFFFF; } uint32_t -NwkAddr::Get (void) const +NwkAddr::Get(void) const { - return m_nwkAddr; + return m_nwkAddr; } // LoraDeviceAddress //////////////////// -LoraDeviceAddress::LoraDeviceAddress () +LoraDeviceAddress::LoraDeviceAddress() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -LoraDeviceAddress::LoraDeviceAddress (uint32_t address) +LoraDeviceAddress::LoraDeviceAddress(uint32_t address) { - NS_LOG_FUNCTION (this << address); + NS_LOG_FUNCTION(this << address); - Set (address); + Set(address); } -LoraDeviceAddress::LoraDeviceAddress (uint8_t nwkId, uint32_t nwkAddr) +LoraDeviceAddress::LoraDeviceAddress(uint8_t nwkId, uint32_t nwkAddr) { - NS_LOG_FUNCTION (this << unsigned(nwkId) << nwkAddr); + NS_LOG_FUNCTION(this << unsigned(nwkId) << nwkAddr); - m_nwkId.Set (nwkId); - m_nwkAddr.Set (nwkAddr); + m_nwkId.Set(nwkId); + m_nwkAddr.Set(nwkAddr); } -LoraDeviceAddress::LoraDeviceAddress (NwkID nwkId, NwkAddr nwkAddr) +LoraDeviceAddress::LoraDeviceAddress(NwkID nwkId, NwkAddr nwkAddr) { - NS_LOG_FUNCTION (this << unsigned(nwkId.Get ()) << nwkAddr.Get ()); + NS_LOG_FUNCTION(this << unsigned(nwkId.Get()) << nwkAddr.Get()); - m_nwkId = nwkId; - m_nwkAddr = nwkAddr; + m_nwkId = nwkId; + m_nwkAddr = nwkAddr; } void -LoraDeviceAddress::Serialize (uint8_t buf[4]) const +LoraDeviceAddress::Serialize(uint8_t buf[4]) const { - NS_LOG_FUNCTION (this << &buf); + NS_LOG_FUNCTION(this << &buf); - uint32_t address = Get (); + uint32_t address = Get(); - buf[0] = (address >> 24) & 0xff; - buf[1] = (address >> 16) & 0xff; - buf[2] = (address >> 8) & 0xff; - buf[3] = (address >> 0) & 0xff; + buf[0] = (address >> 24) & 0xff; + buf[1] = (address >> 16) & 0xff; + buf[2] = (address >> 8) & 0xff; + buf[3] = (address >> 0) & 0xff; } LoraDeviceAddress -LoraDeviceAddress::Deserialize (const uint8_t buf[4]) +LoraDeviceAddress::Deserialize(const uint8_t buf[4]) { - NS_LOG_FUNCTION (&buf); - - // Craft the address from the buffer - uint32_t address = 0; - address |= buf[0]; - address <<= 8; - address |= buf[1]; - address <<= 8; - address |= buf[2]; - address <<= 8; - address |= buf[3]; - - return LoraDeviceAddress (address); + NS_LOG_FUNCTION(&buf); + + // Craft the address from the buffer + uint32_t address = 0; + address |= buf[0]; + address <<= 8; + address |= buf[1]; + address <<= 8; + address |= buf[2]; + address <<= 8; + address |= buf[3]; + + return LoraDeviceAddress(address); } Address -LoraDeviceAddress::ConvertTo (void) const +LoraDeviceAddress::ConvertTo(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - uint8_t addressBuffer[4]; - Serialize (addressBuffer); - return Address (GetType (), addressBuffer, 4); + uint8_t addressBuffer[4]; + Serialize(addressBuffer); + return Address(GetType(), addressBuffer, 4); } LoraDeviceAddress -LoraDeviceAddress::ConvertFrom (const Address &address) +LoraDeviceAddress::ConvertFrom(const Address& address) { - // Create the new, empty address - LoraDeviceAddress ad; - uint8_t addressBuffer[4]; - - // Check that the address we want to convert is compatible with a - // LoraDeviceAddress - NS_ASSERT (address.CheckCompatible (GetType (), 4)); - address.CopyTo (addressBuffer); - ad = Deserialize (addressBuffer); - return ad; + // Create the new, empty address + LoraDeviceAddress ad; + uint8_t addressBuffer[4]; + + // Check that the address we want to convert is compatible with a + // LoraDeviceAddress + NS_ASSERT(address.CheckCompatible(GetType(), 4)); + address.CopyTo(addressBuffer); + ad = Deserialize(addressBuffer); + return ad; } uint8_t -LoraDeviceAddress::GetType (void) +LoraDeviceAddress::GetType(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - static uint8_t type = Address::Register (); - return type; + static uint8_t type = Address::Register(); + return type; } uint32_t -LoraDeviceAddress::Get (void) const +LoraDeviceAddress::Get(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - uint32_t address = 0; - uint32_t nwkId = uint32_t (m_nwkId.Get () << 25); - address |= (m_nwkAddr.Get () | nwkId); - NS_LOG_DEBUG ("m_nwkId + m_nwkAddr = " << std::bitset<32> (address)); + uint32_t address = 0; + uint32_t nwkId = uint32_t(m_nwkId.Get() << 25); + address |= (m_nwkAddr.Get() | nwkId); + NS_LOG_DEBUG("m_nwkId + m_nwkAddr = " << std::bitset<32>(address)); - return address; + return address; } void -LoraDeviceAddress::Set (uint32_t address) +LoraDeviceAddress::Set(uint32_t address) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_nwkId.Set (address >> 25); // Only leave the 7 most significant bits - m_nwkAddr.Set (address & 0x1FFFFFF); // Only consider the 25 least significant bits + m_nwkId.Set(address >> 25); // Only leave the 7 most significant bits + m_nwkAddr.Set(address & 0x1FFFFFF); // Only consider the 25 least significant bits } uint8_t -LoraDeviceAddress::GetNwkID (void) +LoraDeviceAddress::GetNwkID(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_nwkId.Get (); + return m_nwkId.Get(); } uint32_t -LoraDeviceAddress::GetNwkAddr (void) +LoraDeviceAddress::GetNwkAddr(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_nwkAddr.Get (); + return m_nwkAddr.Get(); } void -LoraDeviceAddress::SetNwkID (uint8_t nwkId) +LoraDeviceAddress::SetNwkID(uint8_t nwkId) { - NS_LOG_FUNCTION (this << unsigned(nwkId)); + NS_LOG_FUNCTION(this << unsigned(nwkId)); - m_nwkId.Set (nwkId); + m_nwkId.Set(nwkId); } void -LoraDeviceAddress::SetNwkAddr (uint32_t nwkAddr) +LoraDeviceAddress::SetNwkAddr(uint32_t nwkAddr) { - NS_LOG_FUNCTION (this << nwkAddr); + NS_LOG_FUNCTION(this << nwkAddr); - m_nwkAddr.Set (nwkAddr); + m_nwkAddr.Set(nwkAddr); } std::string -LoraDeviceAddress::Print (void) const +LoraDeviceAddress::Print(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - std::string result; - result += std::bitset<7> (m_nwkId.Get ()).to_string (); - result += "|"; - result += std::bitset<25> (m_nwkAddr.Get ()).to_string (); - return result; + std::string result; + result += std::bitset<7>(m_nwkId.Get()).to_string(); + result += "|"; + result += std::bitset<25>(m_nwkAddr.Get()).to_string(); + return result; } -bool LoraDeviceAddress::operator== - (const LoraDeviceAddress &other) const +bool +LoraDeviceAddress::operator==(const LoraDeviceAddress& other) const { - return this->Get () == other.Get (); + return this->Get() == other.Get(); } -bool LoraDeviceAddress::operator!= - (const LoraDeviceAddress &other) const +bool +LoraDeviceAddress::operator!=(const LoraDeviceAddress& other) const { - return this->Get () != other.Get (); + return this->Get() != other.Get(); } -bool LoraDeviceAddress::operator< - (const LoraDeviceAddress &other) const +bool +LoraDeviceAddress::operator<(const LoraDeviceAddress& other) const { - return this->Get () < other.Get (); + return this->Get() < other.Get(); } -bool LoraDeviceAddress::operator> - (const LoraDeviceAddress &other) const +bool +LoraDeviceAddress::operator>(const LoraDeviceAddress& other) const { - return !(this->Get () < other.Get ()); + return !(this->Get() < other.Get()); } -std::ostream& operator<< (std::ostream& os, const LoraDeviceAddress &address) +std::ostream& +operator<<(std::ostream& os, const LoraDeviceAddress& address) { - os << address.Print (); - return os; -} -} + os << address.Print(); + return os; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-device-address.h b/model/lora-device-address.h index bc47c23d52..55f713d48e 100644 --- a/model/lora-device-address.h +++ b/model/lora-device-address.h @@ -22,39 +22,42 @@ #define LORA_DEVICE_ADDRESS_H #include "ns3/address.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Class representing the NetworkId component of a LoraDeviceAddress (7 bits). */ class NwkID { -public: - NwkID (uint8_t nwkId = 0); - - /** - * Set the NwkID, starting from a 8-bit representation of a 7-bit integer. - * - * This method will ignore the most significant bit of the argument. This - * means that all arguments such that nwkId > 127 will actually be - * considered as nwkId mod 127. - * - * \param nwkId The Network Id value to set. - */ - void Set (uint8_t nwkId); - - /** - * Get an uint8_t representation of the 7-bit network ID. - * - * \return The Network Id. - */ - uint8_t Get (void) const; - -private: - uint8_t m_nwkId; //!< 8-bit integer representation of the network id + public: + NwkID(uint8_t nwkId = 0); + + /** + * Set the NwkID, starting from a 8-bit representation of a 7-bit integer. + * + * This method will ignore the most significant bit of the argument. This + * means that all arguments such that nwkId > 127 will actually be + * considered as nwkId mod 127. + * + * \param nwkId The Network Id value to set. + */ + void Set(uint8_t nwkId); + + /** + * Get an uint8_t representation of the 7-bit network ID. + * + * \return The Network Id. + */ + uint8_t Get(void) const; + + private: + uint8_t m_nwkId; //!< 8-bit integer representation of the network id }; /** @@ -63,29 +66,29 @@ class NwkID */ class NwkAddr { -public: - NwkAddr (uint32_t nwkId = 0); - - /** - * Set the NwkAddr, starting from a 32-bit representation of a 25-bit integer. - * - * This method will ignore the most significant bits of the argument. This - * means that all arguments such that nwkAddr > 2^25 will actually be - * considered as nwkAddr mod 2^25. - * - * \param nwkAddr The Network Address to set. - */ - void Set (uint32_t nwkAddr); - - /** - * Get an uint32_t representation of the 25-bit network address. - * - * \return The Network Address. - */ - uint32_t Get (void) const; - -private: - uint32_t m_nwkAddr; //!< 8-bit integer representation of the network id + public: + NwkAddr(uint32_t nwkId = 0); + + /** + * Set the NwkAddr, starting from a 32-bit representation of a 25-bit integer. + * + * This method will ignore the most significant bits of the argument. This + * means that all arguments such that nwkAddr > 2^25 will actually be + * considered as nwkAddr mod 2^25. + * + * \param nwkAddr The Network Address to set. + */ + void Set(uint32_t nwkAddr); + + /** + * Get an uint32_t representation of the 25-bit network address. + * + * \return The Network Address. + */ + uint32_t Get(void) const; + + private: + uint32_t m_nwkAddr; //!< 8-bit integer representation of the network id }; /** @@ -93,127 +96,127 @@ class NwkAddr */ class LoraDeviceAddress { -public: - LoraDeviceAddress (); - - /** - * Build a new address from a 32-bit integer. - */ - LoraDeviceAddress (uint32_t address); - - /** - * Build a new address from a network id and network address. - */ - LoraDeviceAddress (uint8_t nwkId, uint32_t nwkAddr); - - /** - * Build a new address from a network id and network address. - */ - LoraDeviceAddress (NwkID nwkId, NwkAddr nwkAddr); - - /** - * Convert this address to a buffer. - */ - void Serialize (uint8_t buf[4]) const; - - /** - * Convert the input buffer into a new address. - */ - static LoraDeviceAddress Deserialize (const uint8_t buf[4]); - - /** - * Convert from an ordinary address to a LoraDeviceAddress instance. - */ - static LoraDeviceAddress ConvertFrom (const Address &address); - - /** - * Set the address as a 32 bit integer. - */ - void Set (uint32_t address); - - /** - * Set the address, combining a network id and a network address. - * - * Note that nwkId is 7 bits long, and this function expects the 7 least - * significant bits to contain the nwkId. Similarly for the nwkAddr, the 25 - * least signficant bits of the uint32 are those that are expected to - * contain the nwkAddr. - */ - void Set (uint8_t nwkId, uint32_t nwkAddr); - - /** - * Get the address in 32-bit integer form. - */ - uint32_t Get (void) const; - - /** - * Get the NwkID of this device. - * - * \remark The NwkID bit-by-bit representation will be contained in the 7 - * least significant bits of the returned uint8_t. - * - * \return An 8-bit representation of the Network Id of this Device Address. - */ - uint8_t GetNwkID (void); - - /** - * Set the NwkID of this device. - * - * \remark The NwkID is expected to be contained on the 7 least significant - * bits of the uint8_t. - * - * \param nwkId The network id to set. - */ - void SetNwkID (uint8_t nwkId); - - /** - * Get the NwkAddr of this device. - * - * \remark The NwkAddr will be contained on the 25 least significant bits of - * the uint32_t. - * - * \return A 32-bit representation of the Network Address of this Device Address. - */ - uint32_t GetNwkAddr (void); - - /** - * Set the NwkAddr of this device. - * - * \remark The NwkAddr is expected to be contained on the least significant - * bits of the uint32_t. - * - * \param nwkAddr The network address to set. - */ - void SetNwkAddr (uint32_t nwkAddr); - - /** - * Print the address bit-by-bit to a human-readable string. - * - * \return The string containing the network address. - */ - std::string Print (void) const; - - bool operator== (const LoraDeviceAddress &other) const; - bool operator!= (const LoraDeviceAddress &other) const; - bool operator< (const LoraDeviceAddress &other) const; - bool operator> (const LoraDeviceAddress &other) const; - -private: - /** - * Convert this instance of LoraDeviceAddress to an Address - */ - Address ConvertTo (void) const; - static uint8_t GetType (void); - NwkID m_nwkId; //!< The network Id of this address - NwkAddr m_nwkAddr; //!< The network address of this address + public: + LoraDeviceAddress(); + + /** + * Build a new address from a 32-bit integer. + */ + LoraDeviceAddress(uint32_t address); + + /** + * Build a new address from a network id and network address. + */ + LoraDeviceAddress(uint8_t nwkId, uint32_t nwkAddr); + + /** + * Build a new address from a network id and network address. + */ + LoraDeviceAddress(NwkID nwkId, NwkAddr nwkAddr); + + /** + * Convert this address to a buffer. + */ + void Serialize(uint8_t buf[4]) const; + + /** + * Convert the input buffer into a new address. + */ + static LoraDeviceAddress Deserialize(const uint8_t buf[4]); + + /** + * Convert from an ordinary address to a LoraDeviceAddress instance. + */ + static LoraDeviceAddress ConvertFrom(const Address& address); + + /** + * Set the address as a 32 bit integer. + */ + void Set(uint32_t address); + + /** + * Set the address, combining a network id and a network address. + * + * Note that nwkId is 7 bits long, and this function expects the 7 least + * significant bits to contain the nwkId. Similarly for the nwkAddr, the 25 + * least signficant bits of the uint32 are those that are expected to + * contain the nwkAddr. + */ + void Set(uint8_t nwkId, uint32_t nwkAddr); + + /** + * Get the address in 32-bit integer form. + */ + uint32_t Get(void) const; + + /** + * Get the NwkID of this device. + * + * \remark The NwkID bit-by-bit representation will be contained in the 7 + * least significant bits of the returned uint8_t. + * + * \return An 8-bit representation of the Network Id of this Device Address. + */ + uint8_t GetNwkID(void); + + /** + * Set the NwkID of this device. + * + * \remark The NwkID is expected to be contained on the 7 least significant + * bits of the uint8_t. + * + * \param nwkId The network id to set. + */ + void SetNwkID(uint8_t nwkId); + + /** + * Get the NwkAddr of this device. + * + * \remark The NwkAddr will be contained on the 25 least significant bits of + * the uint32_t. + * + * \return A 32-bit representation of the Network Address of this Device Address. + */ + uint32_t GetNwkAddr(void); + + /** + * Set the NwkAddr of this device. + * + * \remark The NwkAddr is expected to be contained on the least significant + * bits of the uint32_t. + * + * \param nwkAddr The network address to set. + */ + void SetNwkAddr(uint32_t nwkAddr); + + /** + * Print the address bit-by-bit to a human-readable string. + * + * \return The string containing the network address. + */ + std::string Print(void) const; + + bool operator==(const LoraDeviceAddress& other) const; + bool operator!=(const LoraDeviceAddress& other) const; + bool operator<(const LoraDeviceAddress& other) const; + bool operator>(const LoraDeviceAddress& other) const; + + private: + /** + * Convert this instance of LoraDeviceAddress to an Address + */ + Address ConvertTo(void) const; + static uint8_t GetType(void); + NwkID m_nwkId; //!< The network Id of this address + NwkAddr m_nwkAddr; //!< The network address of this address }; /** * Operator overload to correctly handle logging when an address is passed as * an argument. */ -std::ostream& operator<< (std::ostream& os, const LoraDeviceAddress &address); +std::ostream& operator<<(std::ostream& os, const LoraDeviceAddress& address); -} -} +} // namespace lorawan +} // namespace ns3 #endif diff --git a/model/lora-frame-header.cc b/model/lora-frame-header.cc index ecd02d6599..a2c6e127ea 100644 --- a/model/lora-frame-header.cc +++ b/model/lora-frame-header.cc @@ -18,597 +18,587 @@ * Author: Davide Magrin */ -#include "ns3/lora-frame-header.h" +#include "lora-frame-header.h" + #include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraFrameHeader"); +NS_LOG_COMPONENT_DEFINE("LoraFrameHeader"); // Initialization list -LoraFrameHeader::LoraFrameHeader () : - m_fPort (0), - m_address (LoraDeviceAddress (0,0)), - m_adr (0), - m_adrAckReq (0), - m_ack (0), - m_fPending (0), - m_fOptsLen (0), - m_fCnt (0) +LoraFrameHeader::LoraFrameHeader() + : m_fPort(0), + m_address(LoraDeviceAddress(0, 0)), + m_adr(0), + m_adrAckReq(0), + m_ack(0), + m_fPending(0), + m_fOptsLen(0), + m_fCnt(0) { } -LoraFrameHeader::~LoraFrameHeader () +LoraFrameHeader::~LoraFrameHeader() { } TypeId -LoraFrameHeader::GetTypeId (void) +LoraFrameHeader::GetTypeId(void) { - static TypeId tid = TypeId ("LoraFrameHeader") - .SetParent
() - .AddConstructor () - ; - return tid; + static TypeId tid = + TypeId("LoraFrameHeader").SetParent
().AddConstructor(); + return tid; } TypeId -LoraFrameHeader::GetInstanceTypeId (void) const +LoraFrameHeader::GetInstanceTypeId(void) const { - return GetTypeId (); + return GetTypeId(); } uint32_t -LoraFrameHeader::GetSerializedSize (void) const +LoraFrameHeader::GetSerializedSize(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Sizes in bytes: - // 4 for DevAddr + 1 for FCtrl + 2 for FCnt + 1 for FPort + 0-15 for FOpts - uint32_t size = 8 + m_fOptsLen; + // Sizes in bytes: + // 4 for DevAddr + 1 for FCtrl + 2 for FCnt + 1 for FPort + 0-15 for FOpts + uint32_t size = 8 + m_fOptsLen; - NS_LOG_INFO ("LoraFrameHeader serialized size: " << size); + NS_LOG_INFO("LoraFrameHeader serialized size: " << size); - return size; + return size; } void -LoraFrameHeader::Serialize (Buffer::Iterator start) const -{ - NS_LOG_FUNCTION_NOARGS (); - - // Device Address field - start.WriteU32 (m_address.Get ()); - - // fCtrl field - // - // TODO FCtrl has different meanings for UL and DL packets. Handle this - // correctly here. - uint8_t fCtrl = 0; - fCtrl |= uint8_t (m_adr << 7 & 0b10000000); - fCtrl |= uint8_t (m_adrAckReq << 6 & 0b1000000); - fCtrl |= uint8_t (m_ack << 5 & 0b100000); - fCtrl |= uint8_t (m_fPending << 4 & 0b10000); - fCtrl |= m_fOptsLen & 0b1111; - start.WriteU8 (fCtrl); - - // FCnt field - start.WriteU16 (m_fCnt); - - // FOpts field - for (auto it = m_macCommands.begin (); it != m_macCommands.end (); it++) +LoraFrameHeader::Serialize(Buffer::Iterator start) const +{ + NS_LOG_FUNCTION_NOARGS(); + + // Device Address field + start.WriteU32(m_address.Get()); + + // fCtrl field + // + // TODO FCtrl has different meanings for UL and DL packets. Handle this + // correctly here. + uint8_t fCtrl = 0; + fCtrl |= uint8_t(m_adr << 7 & 0b10000000); + fCtrl |= uint8_t(m_adrAckReq << 6 & 0b1000000); + fCtrl |= uint8_t(m_ack << 5 & 0b100000); + fCtrl |= uint8_t(m_fPending << 4 & 0b10000); + fCtrl |= m_fOptsLen & 0b1111; + start.WriteU8(fCtrl); + + // FCnt field + start.WriteU16(m_fCnt); + + // FOpts field + for (auto it = m_macCommands.begin(); it != m_macCommands.end(); it++) { - NS_LOG_DEBUG ("Serializing a MAC command"); - (*it)->Serialize (start); + NS_LOG_DEBUG("Serializing a MAC command"); + (*it)->Serialize(start); } - // FPort - start.WriteU8 (m_fPort); + // FPort + start.WriteU8(m_fPort); - NS_LOG_DEBUG ("Serializing the following data: "); - NS_LOG_DEBUG ("Address: " << m_address.Print ()); - NS_LOG_DEBUG ("ADR: " << unsigned(m_adr)); - NS_LOG_DEBUG ("ADRAckReq: " << unsigned (m_adrAckReq)); - NS_LOG_DEBUG ("Ack: " << unsigned (m_ack)); - NS_LOG_DEBUG ("fPending: " << unsigned (m_fPending)); - NS_LOG_DEBUG ("fOptsLen: " << unsigned (m_fOptsLen)); - NS_LOG_DEBUG ("fCnt: " << unsigned (m_fCnt)); + NS_LOG_DEBUG("Serializing the following data: "); + NS_LOG_DEBUG("Address: " << m_address.Print()); + NS_LOG_DEBUG("ADR: " << unsigned(m_adr)); + NS_LOG_DEBUG("ADRAckReq: " << unsigned(m_adrAckReq)); + NS_LOG_DEBUG("Ack: " << unsigned(m_ack)); + NS_LOG_DEBUG("fPending: " << unsigned(m_fPending)); + NS_LOG_DEBUG("fOptsLen: " << unsigned(m_fOptsLen)); + NS_LOG_DEBUG("fCnt: " << unsigned(m_fCnt)); } uint32_t -LoraFrameHeader::Deserialize (Buffer::Iterator start) -{ - NS_LOG_FUNCTION_NOARGS (); - - // Empty the list of MAC commands - m_macCommands.clear (); - - // Read from buffer and save into local variables - m_address.Set (start.ReadU32 ()); - // TODO FCtrl has different meanings for UL and DL packets. Handle this - // correctly here. - uint8_t fCtrl = start.ReadU8 (); - m_adr = (fCtrl >> 7) & 0b1; - m_adrAckReq = (fCtrl >> 6) & 0b1; - m_ack = (fCtrl >> 5) & 0b1; - m_fPending = (fCtrl >> 4) & 0b1; - m_fOptsLen = fCtrl & 0b1111; - m_fCnt = start.ReadU16 (); - - NS_LOG_DEBUG ("Deserialized data: "); - NS_LOG_DEBUG ("Address: " << m_address.Print ()); - NS_LOG_DEBUG ("ADR: " << unsigned(m_adr)); - NS_LOG_DEBUG ("ADRAckReq: " << unsigned (m_adrAckReq)); - NS_LOG_DEBUG ("Ack: " << unsigned (m_ack)); - NS_LOG_DEBUG ("fPending: " << unsigned (m_fPending)); - NS_LOG_DEBUG ("fOptsLen: " << unsigned (m_fOptsLen)); - NS_LOG_DEBUG ("fCnt: " << unsigned (m_fCnt)); - - // Deserialize MAC commands - NS_LOG_DEBUG ("Starting deserialization of MAC commands"); - for (uint8_t byteNumber = 0; byteNumber < m_fOptsLen;) +LoraFrameHeader::Deserialize(Buffer::Iterator start) +{ + NS_LOG_FUNCTION_NOARGS(); + + // Empty the list of MAC commands + m_macCommands.clear(); + + // Read from buffer and save into local variables + m_address.Set(start.ReadU32()); + // TODO FCtrl has different meanings for UL and DL packets. Handle this + // correctly here. + uint8_t fCtrl = start.ReadU8(); + m_adr = (fCtrl >> 7) & 0b1; + m_adrAckReq = (fCtrl >> 6) & 0b1; + m_ack = (fCtrl >> 5) & 0b1; + m_fPending = (fCtrl >> 4) & 0b1; + m_fOptsLen = fCtrl & 0b1111; + m_fCnt = start.ReadU16(); + + NS_LOG_DEBUG("Deserialized data: "); + NS_LOG_DEBUG("Address: " << m_address.Print()); + NS_LOG_DEBUG("ADR: " << unsigned(m_adr)); + NS_LOG_DEBUG("ADRAckReq: " << unsigned(m_adrAckReq)); + NS_LOG_DEBUG("Ack: " << unsigned(m_ack)); + NS_LOG_DEBUG("fPending: " << unsigned(m_fPending)); + NS_LOG_DEBUG("fOptsLen: " << unsigned(m_fOptsLen)); + NS_LOG_DEBUG("fCnt: " << unsigned(m_fCnt)); + + // Deserialize MAC commands + NS_LOG_DEBUG("Starting deserialization of MAC commands"); + for (uint8_t byteNumber = 0; byteNumber < m_fOptsLen;) { - uint8_t cid = start.PeekU8 (); - NS_LOG_DEBUG ("CID: " << unsigned(cid)); - - // Divide Uplink and Downlink messages - // This needs to be done because they have the same CID, and the context - // about where this message will be Serialized/Deserialized (i.e., at the - // ED or at the NS) is umportant. - if (m_isUplink) + uint8_t cid = start.PeekU8(); + NS_LOG_DEBUG("CID: " << unsigned(cid)); + + // Divide Uplink and Downlink messages + // This needs to be done because they have the same CID, and the context + // about where this message will be Serialized/Deserialized (i.e., at the + // ED or at the NS) is umportant. + if (m_isUplink) { - switch (cid) + switch (cid) { // In the case of Uplink messages, the NS will deserialize the // request for a link check - case (0x02): - { - NS_LOG_DEBUG ("Creating a LinkCheckReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + case (0x02): { + NS_LOG_DEBUG("Creating a LinkCheckReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x03): - { - NS_LOG_DEBUG ("Creating a LinkAdrAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x03): { + NS_LOG_DEBUG("Creating a LinkAdrAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x04): - { - NS_LOG_DEBUG ("Creating a DutyCycleAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x04): { + NS_LOG_DEBUG("Creating a DutyCycleAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x05): - { - NS_LOG_DEBUG ("Creating a RxParamSetupAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x05): { + NS_LOG_DEBUG("Creating a RxParamSetupAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x06): - { - NS_LOG_DEBUG ("Creating a DevStatusAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x06): { + NS_LOG_DEBUG("Creating a DevStatusAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x07): - { - NS_LOG_DEBUG ("Creating a NewChannelAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x07): { + NS_LOG_DEBUG("Creating a NewChannelAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x08): - { - NS_LOG_DEBUG ("Creating a RxTimingSetupAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x08): { + NS_LOG_DEBUG("Creating a RxTimingSetupAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x09): - { - NS_LOG_DEBUG ("Creating a TxParamSetupAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x09): { + NS_LOG_DEBUG("Creating a TxParamSetupAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x0A): - { - NS_LOG_DEBUG ("Creating a DlChannelAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x0A): { + NS_LOG_DEBUG("Creating a DlChannelAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - default: - { - NS_LOG_ERROR ("CID not recognized during deserialization"); - } + } + default: { + NS_LOG_ERROR("CID not recognized during deserialization"); + } } } - else + else { - switch (cid) + switch (cid) { // In the case of Downlink messages, the ED will deserialize the // answer to a link check - case (0x02): - { - NS_LOG_DEBUG ("Creating a LinkCheckAns command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + case (0x02): { + NS_LOG_DEBUG("Creating a LinkCheckAns command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x03): - { - NS_LOG_DEBUG ("Creating a LinkAdrReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x03): { + NS_LOG_DEBUG("Creating a LinkAdrReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x04): - { - NS_LOG_DEBUG ("Creating a DutyCycleReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x04): { + NS_LOG_DEBUG("Creating a DutyCycleReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x05): - { - NS_LOG_DEBUG ("Creating a RxParamSetupReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x05): { + NS_LOG_DEBUG("Creating a RxParamSetupReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x06): - { - NS_LOG_DEBUG ("Creating a DevStatusReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x06): { + NS_LOG_DEBUG("Creating a DevStatusReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x07): - { - NS_LOG_DEBUG ("Creating a NewChannelReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x07): { + NS_LOG_DEBUG("Creating a NewChannelReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x08): - { - NS_LOG_DEBUG ("Creating a RxTimingSetupReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x08): { + NS_LOG_DEBUG("Creating a RxTimingSetupReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - case (0x09): - { - NS_LOG_DEBUG ("Creating a TxParamSetupReq command"); - Ptr command = Create (); - byteNumber += command->Deserialize (start); - m_macCommands.push_back (command); + } + case (0x09): { + NS_LOG_DEBUG("Creating a TxParamSetupReq command"); + Ptr command = Create(); + byteNumber += command->Deserialize(start); + m_macCommands.push_back(command); break; - } - default: - { - NS_LOG_ERROR ("CID not recognized during deserialization"); - } + } + default: { + NS_LOG_ERROR("CID not recognized during deserialization"); + } } } } - m_fPort = uint8_t (start.ReadU8 ()); + m_fPort = uint8_t(start.ReadU8()); - return 8 + m_fOptsLen; // the number of bytes consumed. + return 8 + m_fOptsLen; // the number of bytes consumed. } void -LoraFrameHeader::Print (std::ostream &os) const +LoraFrameHeader::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "Address=" << m_address.Print () << std::endl; - os << "ADR=" << m_adr << std::endl; - os << "ADRAckReq=" << m_adrAckReq << std::endl; - os << "ACK=" << m_ack << std::endl; - os << "FPending=" << m_fPending << std::endl; - os << "FOptsLen=" << unsigned(m_fOptsLen) << std::endl; - os << "FCnt=" << unsigned(m_fCnt) << std::endl; + os << "Address=" << m_address.Print() << std::endl; + os << "ADR=" << m_adr << std::endl; + os << "ADRAckReq=" << m_adrAckReq << std::endl; + os << "ACK=" << m_ack << std::endl; + os << "FPending=" << m_fPending << std::endl; + os << "FOptsLen=" << unsigned(m_fOptsLen) << std::endl; + os << "FCnt=" << unsigned(m_fCnt) << std::endl; - for (auto it = m_macCommands.begin (); it != m_macCommands.end (); it++) + for (auto it = m_macCommands.begin(); it != m_macCommands.end(); it++) { - (*it)->Print (os); + (*it)->Print(os); } - os << "FPort=" << unsigned(m_fPort) << std::endl; + os << "FPort=" << unsigned(m_fPort) << std::endl; } void -LoraFrameHeader::SetAsUplink (void) +LoraFrameHeader::SetAsUplink(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_isUplink = true; + m_isUplink = true; } void -LoraFrameHeader::SetAsDownlink (void) +LoraFrameHeader::SetAsDownlink(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_isUplink = false; + m_isUplink = false; } void -LoraFrameHeader::SetFPort (uint8_t fPort) +LoraFrameHeader::SetFPort(uint8_t fPort) { - m_fPort = fPort; + m_fPort = fPort; } uint8_t -LoraFrameHeader::GetFPort (void) const +LoraFrameHeader::GetFPort(void) const { - return m_fPort; + return m_fPort; } void -LoraFrameHeader::SetAddress (LoraDeviceAddress address) +LoraFrameHeader::SetAddress(LoraDeviceAddress address) { - m_address = address; + m_address = address; } LoraDeviceAddress -LoraFrameHeader::GetAddress (void) const +LoraFrameHeader::GetAddress(void) const { - return m_address; + return m_address; } void -LoraFrameHeader::SetAdr (bool adr) +LoraFrameHeader::SetAdr(bool adr) { - NS_LOG_FUNCTION (this << adr); - m_adr = adr; + NS_LOG_FUNCTION(this << adr); + m_adr = adr; } + bool -LoraFrameHeader::GetAdr (void) const +LoraFrameHeader::GetAdr(void) const { - return m_adr; + return m_adr; } void -LoraFrameHeader::SetAdrAckReq (bool adrAckReq) +LoraFrameHeader::SetAdrAckReq(bool adrAckReq) { - m_adrAckReq = adrAckReq; + m_adrAckReq = adrAckReq; } + bool -LoraFrameHeader::GetAdrAckReq (void) const +LoraFrameHeader::GetAdrAckReq(void) const { - return m_adrAckReq; + return m_adrAckReq; } void -LoraFrameHeader::SetAck (bool ack) +LoraFrameHeader::SetAck(bool ack) { - NS_LOG_FUNCTION (this << ack); - m_ack = ack; + NS_LOG_FUNCTION(this << ack); + m_ack = ack; } + bool -LoraFrameHeader::GetAck (void) const +LoraFrameHeader::GetAck(void) const { - return m_ack; + return m_ack; } void -LoraFrameHeader::SetFPending (bool fPending) +LoraFrameHeader::SetFPending(bool fPending) { - m_fPending = fPending; + m_fPending = fPending; } + bool -LoraFrameHeader::GetFPending (void) const +LoraFrameHeader::GetFPending(void) const { - return m_fPending; + return m_fPending; } uint8_t -LoraFrameHeader::GetFOptsLen (void) const +LoraFrameHeader::GetFOptsLen(void) const { - // Sum the serialized lenght of all commands in the list - uint8_t fOptsLen = 0; - std::list< Ptr< MacCommand> >::const_iterator it; - for (it = m_macCommands.begin (); it != m_macCommands.end (); it++) + // Sum the serialized lenght of all commands in the list + uint8_t fOptsLen = 0; + std::list>::const_iterator it; + for (it = m_macCommands.begin(); it != m_macCommands.end(); it++) { - fOptsLen = fOptsLen + (*it)->GetSerializedSize (); + fOptsLen = fOptsLen + (*it)->GetSerializedSize(); } - return fOptsLen; + return fOptsLen; } void -LoraFrameHeader::SetFCnt (uint16_t fCnt) +LoraFrameHeader::SetFCnt(uint16_t fCnt) { - m_fCnt = fCnt; + m_fCnt = fCnt; } uint16_t -LoraFrameHeader::GetFCnt (void) const +LoraFrameHeader::GetFCnt(void) const { - return m_fCnt; + return m_fCnt; } void -LoraFrameHeader::AddLinkCheckReq (void) +LoraFrameHeader::AddLinkCheckReq(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - Ptr command = Create (); - m_macCommands.push_back (command); + Ptr command = Create(); + m_macCommands.push_back(command); - NS_LOG_DEBUG ("Command SerializedSize: " << unsigned(command->GetSerializedSize ())); - m_fOptsLen += command->GetSerializedSize (); + NS_LOG_DEBUG("Command SerializedSize: " << unsigned(command->GetSerializedSize())); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddLinkCheckAns (uint8_t margin, uint8_t gwCnt) +LoraFrameHeader::AddLinkCheckAns(uint8_t margin, uint8_t gwCnt) { - NS_LOG_FUNCTION (this << unsigned(margin) << unsigned(gwCnt)); + NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt)); - Ptr command = Create (margin, gwCnt); - m_macCommands.push_back (command); + Ptr command = Create(margin, gwCnt); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddLinkAdrReq (uint8_t dataRate, uint8_t txPower, std::list enabledChannels, int repetitions) +LoraFrameHeader::AddLinkAdrReq(uint8_t dataRate, + uint8_t txPower, + std::list enabledChannels, + int repetitions) { - NS_LOG_FUNCTION (this << unsigned (dataRate) << txPower << repetitions); + NS_LOG_FUNCTION(this << unsigned(dataRate) << txPower << repetitions); - uint16_t channelMask = 0; - for (auto it = enabledChannels.begin (); it != enabledChannels.end (); it++) + uint16_t channelMask = 0; + for (auto it = enabledChannels.begin(); it != enabledChannels.end(); it++) { - NS_ASSERT ((*it) < 16 && (*it) > -1); + NS_ASSERT((*it) < 16 && (*it) > -1); - channelMask |= 0b1 << (*it); + channelMask |= 0b1 << (*it); } - // TODO Implement chMaskCntl field + // TODO Implement chMaskCntl field - NS_LOG_DEBUG ("Creating LinkAdrReq with: DR = " << unsigned(dataRate) << " and txPower = " << unsigned(txPower)); + NS_LOG_DEBUG("Creating LinkAdrReq with: DR = " << unsigned(dataRate) + << " and txPower = " << unsigned(txPower)); - Ptr command = Create (dataRate, txPower, channelMask, 0, repetitions); - m_macCommands.push_back (command); + Ptr command = Create(dataRate, txPower, channelMask, 0, repetitions); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddLinkAdrAns (bool powerAck, bool dataRateAck, bool channelMaskAck) +LoraFrameHeader::AddLinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck) { - NS_LOG_FUNCTION (this << powerAck << dataRateAck << channelMaskAck); + NS_LOG_FUNCTION(this << powerAck << dataRateAck << channelMaskAck); - Ptr command = Create (powerAck, dataRateAck, channelMaskAck); - m_macCommands.push_back (command); + Ptr command = Create(powerAck, dataRateAck, channelMaskAck); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddDutyCycleReq (uint8_t dutyCycle) +LoraFrameHeader::AddDutyCycleReq(uint8_t dutyCycle) { - NS_LOG_FUNCTION (this << unsigned (dutyCycle)); + NS_LOG_FUNCTION(this << unsigned(dutyCycle)); - Ptr command = Create (dutyCycle); + Ptr command = Create(dutyCycle); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddDutyCycleAns (void) +LoraFrameHeader::AddDutyCycleAns(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - Ptr command = Create (); + Ptr command = Create(); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddRxParamSetupReq (uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency) +LoraFrameHeader::AddRxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency) { - NS_LOG_FUNCTION (this << unsigned (rx1DrOffset) << unsigned (rx2DataRate) << - frequency); + NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency); - // Evaluate whether to eliminate this assert in case new offsets can be defined. - NS_ASSERT (0 <= rx1DrOffset && rx1DrOffset <= 5); + // Evaluate whether to eliminate this assert in case new offsets can be defined. + NS_ASSERT(0 <= rx1DrOffset && rx1DrOffset <= 5); - Ptr command = Create (rx1DrOffset, - rx2DataRate, - frequency); + Ptr command = Create(rx1DrOffset, rx2DataRate, frequency); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddRxParamSetupAns (void) +LoraFrameHeader::AddRxParamSetupAns(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - Ptr command = Create (); + Ptr command = Create(); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddDevStatusReq (void) +LoraFrameHeader::AddDevStatusReq(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - Ptr command = Create (); + Ptr command = Create(); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } void -LoraFrameHeader::AddNewChannelReq (uint8_t chIndex, double frequency, - uint8_t minDataRate, uint8_t maxDataRate) +LoraFrameHeader::AddNewChannelReq(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - Ptr command = Create (chIndex, frequency, - minDataRate, maxDataRate); + Ptr command = + Create(chIndex, frequency, minDataRate, maxDataRate); - m_macCommands.push_back (command); + m_macCommands.push_back(command); - m_fOptsLen += command->GetSerializedSize (); + m_fOptsLen += command->GetSerializedSize(); } -std::list > -LoraFrameHeader::GetCommands (void) +std::list> +LoraFrameHeader::GetCommands(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_macCommands; + return m_macCommands; } void -LoraFrameHeader::AddCommand (Ptr macCommand) +LoraFrameHeader::AddCommand(Ptr macCommand) { - NS_LOG_FUNCTION (this << macCommand); + NS_LOG_FUNCTION(this << macCommand); - m_macCommands.push_back (macCommand); - m_fOptsLen += macCommand->GetSerializedSize (); + m_macCommands.push_back(macCommand); + m_fOptsLen += macCommand->GetSerializedSize(); } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-frame-header.h b/model/lora-frame-header.h index 9e3431c924..3fa495c6c9 100644 --- a/model/lora-frame-header.h +++ b/model/lora-frame-header.h @@ -21,12 +21,15 @@ #ifndef LORA_FRAME_HEADER_H #define LORA_FRAME_HEADER_H +#include "lora-device-address.h" +#include "mac-command.h" + #include "ns3/header.h" -#include "ns3/lora-device-address.h" -#include "ns3/mac-command.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class represents the Frame header (FHDR) used in a LoraWAN network. @@ -42,302 +45,308 @@ namespace lorawan { */ class LoraFrameHeader : public Header { -public: - LoraFrameHeader (); - ~LoraFrameHeader (); - - // Methods inherited from Header - static TypeId GetTypeId (void); - virtual TypeId GetInstanceTypeId (void) const; - - /** - * Return the size required for serialization of this header - * - * \return The serialized size in bytes - */ - virtual uint32_t GetSerializedSize (void) const; - - /** - * Serialize the header. - * - * See Page 15 of LoraWAN specification for a representation of fields. - * - * \param start A pointer to the buffer that will be filled with the - * serialization. - */ - virtual void Serialize (Buffer::Iterator start) const; - - /** - * Deserialize the contents of the buffer into a LoraFrameHeader object. - * - * \param start A pointer to the buffer we need to deserialize. - * \return The number of consumed bytes. - */ - virtual uint32_t Deserialize (Buffer::Iterator start); - - /** - * Print the header in a human-readable format. - * - * \param os The std::ostream on which to print the header. - */ - virtual void Print (std::ostream &os) const; - - /** - * State that this is an uplink message. - * - * This method needs to be called at least once before any serialization or - * deserialization. - */ - void SetAsUplink (void); - - /** - * State that this is a downlink message. - * - * This method needs to be called at least once before any serialization or - * deserialization. - */ - void SetAsDownlink (void); - - /** - * Set the FPort value. - * - * \param fPort The FPort to set. - */ - void SetFPort (uint8_t fPort); - - /** - * Get the FPort value. - * - * \return The FPort value. - */ - uint8_t GetFPort (void) const; - - /** - * Set the address. - * - * \param address The LoraDeviceAddress to set. - */ - void SetAddress (LoraDeviceAddress address); - - /** - * Get this header's device address value. - * - * \return The address value stored in this header. - */ - LoraDeviceAddress GetAddress (void) const; - - /** - * Set the Adr value. - * - * \param Adr The Adr to set. - */ - void SetAdr (bool adr); - - /** - * Get the Adr value. - * - * \return The Adr value. - */ - bool GetAdr (void) const; - - /** - * Set the AdrAckReq value. - * - * \param adrAckReq The AdrAckReq to set. - */ - void SetAdrAckReq (bool adrAckReq); - - /** - * Get the AdrAckReq value. - * - * \return The AdrAckReq value. - */ - bool GetAdrAckReq (void) const; - - /** - * Set the Ack bit. - * - * \param ack Whether or not to set the ACK bit. - */ - void SetAck (bool ack); - - /** - * Get the Ack bit value. - * - * \return True if the ACK bit is set, false otherwise. - */ - bool GetAck (void) const; - - /** - * Set the FPending value. - * - * \param fPending The FPending to set. - */ - void SetFPending (bool fPending); - - /** - * Get the FPending value. - * - * \return The FPending value. - */ - bool GetFPending (void) const; - - /** - * Get the FOptsLen value. - * - * \remark This value cannot be set since it's directly extracted from the - * number and kind of MAC commands. - * - * \return The FOptsLen value. - */ - uint8_t GetFOptsLen (void) const; - - /** - * Set the FCnt value - * - * \param FCnt The FCnt to set. - */ - void SetFCnt (uint16_t fCnt); - /** - * Get the FCnt value. - * - * \return The FCnt value. - */ - uint16_t GetFCnt (void) const; - - /** - * Return a pointer to a MacCommand, or 0 if the MacCommand does not exist - * in this header. - */ - template - inline Ptr GetMacCommand (void); - - /** - * Add a LinkCheckReq command. - */ - void AddLinkCheckReq (void); - - /** - * Add a LinkCheckAns command. - * - * \param margin The demodulation margin the LinkCheckReq packet was received with. - * \param gwCnt The number of gateways the LinkCheckReq packet was received by. - */ - void AddLinkCheckAns (uint8_t margin, uint8_t gwCnt); - - /** - * Add a LinkAdrReq command. - * - * \param dataRate The data rate at which the receiver should transmit. - * \param txPower The power at which the receiver should transmit, encoded according to the LoRaWAN specification of the region. - * \param enabledChannels A list containing the indices of channels enabled by this command. - * \param repetitions The number of repetitions the receiver should send when transmitting. - */ - void AddLinkAdrReq (uint8_t dataRate, uint8_t txPower, std::list enabledChannels, int repetitions); - - /** - * Add a LinkAdrAns command. - * - * \param powerAck Whether the power can be set or not. - * \param dataRateAck Whether the data rate can be set or not. - * \param channelMaskAck Whether the channel mask is coherent with the device's current state or not. - */ - void AddLinkAdrAns (bool powerAck, bool dataRateAck, bool channelMaskAck); - - /** - * Add a DutyCycleReq command. - * - * This command accepts an 8-bit integer as dutyCycle. The actual dutyCycle - * that will be implemented in the end-device will then be, in fraction form, - * 1/2^(dutyCycle). - * - * \param dutyCycle The dutyCycle in 8-bit form. - */ - void AddDutyCycleReq (uint8_t dutyCycle); - - /** - * Add a DutyCycleAns command. - */ - void AddDutyCycleAns (void); - - /** - * Add a RxParamSetupReq command. - * - * \param rx1DrOffset The requested data rate offset for the first receive window. - * \param rx2DataRate The requested data rate for the second receive window. - * \param frequency The frequency at which to listen for the second receive window. - */ - void AddRxParamSetupReq (uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency); - - /** - * Add a RxParamSetupAns command. - */ - void AddRxParamSetupAns (); - - /** - * Add a DevStatusReq command. - */ - void AddDevStatusReq (); - - /** - * Add a NewChannelReq command. - */ - void AddNewChannelReq (uint8_t chIndex, double frequency, uint8_t minDataRate, - uint8_t maxDataRate); - - /** - * Return a list of pointers to all the MAC commands saved in this header. - */ - std::list > GetCommands (void); - - /** - * Add a predefined command to the list. - */ - void AddCommand (Ptr macCommand); - -private: - uint8_t m_fPort; - - LoraDeviceAddress m_address; - - bool m_adr; - bool m_adrAckReq; - bool m_ack; - bool m_fPending; - uint8_t m_fOptsLen; - - uint16_t m_fCnt; - - Buffer m_fOpts; - - /** - * List containing all the MacCommand instances that are contained in this - * LoraFrameHeader. - */ - std::list< Ptr< MacCommand> > m_macCommands; - - bool m_isUplink; + public: + LoraFrameHeader(); + ~LoraFrameHeader(); + + // Methods inherited from Header + static TypeId GetTypeId(void); + virtual TypeId GetInstanceTypeId(void) const; + + /** + * Return the size required for serialization of this header + * + * \return The serialized size in bytes + */ + virtual uint32_t GetSerializedSize(void) const; + + /** + * Serialize the header. + * + * See Page 15 of LoraWAN specification for a representation of fields. + * + * \param start A pointer to the buffer that will be filled with the + * serialization. + */ + virtual void Serialize(Buffer::Iterator start) const; + + /** + * Deserialize the contents of the buffer into a LoraFrameHeader object. + * + * \param start A pointer to the buffer we need to deserialize. + * \return The number of consumed bytes. + */ + virtual uint32_t Deserialize(Buffer::Iterator start); + + /** + * Print the header in a human-readable format. + * + * \param os The std::ostream on which to print the header. + */ + virtual void Print(std::ostream& os) const; + + /** + * State that this is an uplink message. + * + * This method needs to be called at least once before any serialization or + * deserialization. + */ + void SetAsUplink(void); + + /** + * State that this is a downlink message. + * + * This method needs to be called at least once before any serialization or + * deserialization. + */ + void SetAsDownlink(void); + + /** + * Set the FPort value. + * + * \param fPort The FPort to set. + */ + void SetFPort(uint8_t fPort); + + /** + * Get the FPort value. + * + * \return The FPort value. + */ + uint8_t GetFPort(void) const; + + /** + * Set the address. + * + * \param address The LoraDeviceAddress to set. + */ + void SetAddress(LoraDeviceAddress address); + + /** + * Get this header's device address value. + * + * \return The address value stored in this header. + */ + LoraDeviceAddress GetAddress(void) const; + + /** + * Set the Adr value. + * + * \param Adr The Adr to set. + */ + void SetAdr(bool adr); + + /** + * Get the Adr value. + * + * \return The Adr value. + */ + bool GetAdr(void) const; + + /** + * Set the AdrAckReq value. + * + * \param adrAckReq The AdrAckReq to set. + */ + void SetAdrAckReq(bool adrAckReq); + + /** + * Get the AdrAckReq value. + * + * \return The AdrAckReq value. + */ + bool GetAdrAckReq(void) const; + + /** + * Set the Ack bit. + * + * \param ack Whether or not to set the ACK bit. + */ + void SetAck(bool ack); + + /** + * Get the Ack bit value. + * + * \return True if the ACK bit is set, false otherwise. + */ + bool GetAck(void) const; + + /** + * Set the FPending value. + * + * \param fPending The FPending to set. + */ + void SetFPending(bool fPending); + + /** + * Get the FPending value. + * + * \return The FPending value. + */ + bool GetFPending(void) const; + + /** + * Get the FOptsLen value. + * + * \remark This value cannot be set since it's directly extracted from the + * number and kind of MAC commands. + * + * \return The FOptsLen value. + */ + uint8_t GetFOptsLen(void) const; + + /** + * Set the FCnt value + * + * \param FCnt The FCnt to set. + */ + void SetFCnt(uint16_t fCnt); + /** + * Get the FCnt value. + * + * \return The FCnt value. + */ + uint16_t GetFCnt(void) const; + + /** + * Return a pointer to a MacCommand, or 0 if the MacCommand does not exist + * in this header. + */ + template + inline Ptr GetMacCommand(void); + + /** + * Add a LinkCheckReq command. + */ + void AddLinkCheckReq(void); + + /** + * Add a LinkCheckAns command. + * + * \param margin The demodulation margin the LinkCheckReq packet was received with. + * \param gwCnt The number of gateways the LinkCheckReq packet was received by. + */ + void AddLinkCheckAns(uint8_t margin, uint8_t gwCnt); + + /** + * Add a LinkAdrReq command. + * + * \param dataRate The data rate at which the receiver should transmit. + * \param txPower The power at which the receiver should transmit, encoded according to the + * LoRaWAN specification of the region. \param enabledChannels A list containing the indices of + * channels enabled by this command. \param repetitions The number of repetitions the receiver + * should send when transmitting. + */ + void AddLinkAdrReq(uint8_t dataRate, + uint8_t txPower, + std::list enabledChannels, + int repetitions); + + /** + * Add a LinkAdrAns command. + * + * \param powerAck Whether the power can be set or not. + * \param dataRateAck Whether the data rate can be set or not. + * \param channelMaskAck Whether the channel mask is coherent with the device's current state or + * not. + */ + void AddLinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck); + + /** + * Add a DutyCycleReq command. + * + * This command accepts an 8-bit integer as dutyCycle. The actual dutyCycle + * that will be implemented in the end-device will then be, in fraction form, + * 1/2^(dutyCycle). + * + * \param dutyCycle The dutyCycle in 8-bit form. + */ + void AddDutyCycleReq(uint8_t dutyCycle); + + /** + * Add a DutyCycleAns command. + */ + void AddDutyCycleAns(void); + + /** + * Add a RxParamSetupReq command. + * + * \param rx1DrOffset The requested data rate offset for the first receive window. + * \param rx2DataRate The requested data rate for the second receive window. + * \param frequency The frequency at which to listen for the second receive window. + */ + void AddRxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency); + + /** + * Add a RxParamSetupAns command. + */ + void AddRxParamSetupAns(); + + /** + * Add a DevStatusReq command. + */ + void AddDevStatusReq(); + + /** + * Add a NewChannelReq command. + */ + void AddNewChannelReq(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate); + + /** + * Return a list of pointers to all the MAC commands saved in this header. + */ + std::list> GetCommands(void); + + /** + * Add a predefined command to the list. + */ + void AddCommand(Ptr macCommand); + + private: + uint8_t m_fPort; + + LoraDeviceAddress m_address; + + bool m_adr; + bool m_adrAckReq; + bool m_ack; + bool m_fPending; + uint8_t m_fOptsLen; + + uint16_t m_fCnt; + + Buffer m_fOpts; + + /** + * List containing all the MacCommand instances that are contained in this + * LoraFrameHeader. + */ + std::list> m_macCommands; + + bool m_isUplink; }; - -template +template Ptr -LoraFrameHeader::GetMacCommand () +LoraFrameHeader::GetMacCommand() { - // Iterate on MAC commands and try casting - std::list< Ptr< MacCommand> >::const_iterator it; - for (it = m_macCommands.begin (); it != m_macCommands.end (); ++it) + // Iterate on MAC commands and try casting + std::list>::const_iterator it; + for (it = m_macCommands.begin(); it != m_macCommands.end(); ++it) { - if ((*it)->GetObject ()) + if ((*it)->GetObject()) { - return (*it)->GetObject (); + return (*it)->GetObject(); } } - // If no command was found, return 0 - return 0; -} + // If no command was found, return 0 + return 0; } +} // namespace lorawan -} +} // namespace ns3 #endif diff --git a/model/lora-interference-helper.cc b/model/lora-interference-helper.cc index ce43e49262..2cdde3d6c7 100644 --- a/model/lora-interference-helper.cc +++ b/model/lora-interference-helper.cc @@ -18,95 +18,102 @@ * Author: Davide Magrin */ -#include "ns3/lora-interference-helper.h" -#include "ns3/log.h" +#include "lora-interference-helper.h" + #include "ns3/enum.h" +#include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraInterferenceHelper"); +NS_LOG_COMPONENT_DEFINE("LoraInterferenceHelper"); /*************************************** * LoraInterferenceHelper::Event * ***************************************/ // Event Constructor -LoraInterferenceHelper::Event::Event (Time duration, double rxPowerdBm, uint8_t spreadingFactor, - Ptr packet, double frequencyMHz) - : m_startTime (Simulator::Now ()), - m_endTime (m_startTime + duration), - m_sf (spreadingFactor), - m_rxPowerdBm (rxPowerdBm), - m_packet (packet), - m_frequencyMHz (frequencyMHz) +LoraInterferenceHelper::Event::Event(Time duration, + double rxPowerdBm, + uint8_t spreadingFactor, + Ptr packet, + double frequencyMHz) + : m_startTime(Simulator::Now()), + m_endTime(m_startTime + duration), + m_sf(spreadingFactor), + m_rxPowerdBm(rxPowerdBm), + m_packet(packet), + m_frequencyMHz(frequencyMHz) { - // NS_LOG_FUNCTION_NOARGS (); + // NS_LOG_FUNCTION_NOARGS (); } // Event Destructor -LoraInterferenceHelper::Event::~Event () +LoraInterferenceHelper::Event::~Event() { - // NS_LOG_FUNCTION_NOARGS (); + // NS_LOG_FUNCTION_NOARGS (); } // Getters Time -LoraInterferenceHelper::Event::GetStartTime (void) const +LoraInterferenceHelper::Event::GetStartTime(void) const { - return m_startTime; + return m_startTime; } Time -LoraInterferenceHelper::Event::GetEndTime (void) const +LoraInterferenceHelper::Event::GetEndTime(void) const { - return m_endTime; + return m_endTime; } Time -LoraInterferenceHelper::Event::GetDuration (void) const +LoraInterferenceHelper::Event::GetDuration(void) const { - return m_endTime - m_startTime; + return m_endTime - m_startTime; } double -LoraInterferenceHelper::Event::GetRxPowerdBm (void) const +LoraInterferenceHelper::Event::GetRxPowerdBm(void) const { - return m_rxPowerdBm; + return m_rxPowerdBm; } uint8_t -LoraInterferenceHelper::Event::GetSpreadingFactor (void) const +LoraInterferenceHelper::Event::GetSpreadingFactor(void) const { - return m_sf; + return m_sf; } Ptr -LoraInterferenceHelper::Event::GetPacket (void) const +LoraInterferenceHelper::Event::GetPacket(void) const { - return m_packet; + return m_packet; } double -LoraInterferenceHelper::Event::GetFrequency (void) const +LoraInterferenceHelper::Event::GetFrequency(void) const { - return m_frequencyMHz; + return m_frequencyMHz; } void -LoraInterferenceHelper::Event::Print (std::ostream &stream) const +LoraInterferenceHelper::Event::Print(std::ostream& stream) const { - stream << "(" << m_startTime.GetSeconds () << " s - " << m_endTime.GetSeconds () << " s), SF" - << unsigned(m_sf) << ", " << m_rxPowerdBm << " dBm, " << m_frequencyMHz << " MHz"; + stream << "(" << m_startTime.GetSeconds() << " s - " << m_endTime.GetSeconds() << " s), SF" + << unsigned(m_sf) << ", " << m_rxPowerdBm << " dBm, " << m_frequencyMHz << " MHz"; } -std::ostream & -operator<< (std::ostream &os, const LoraInterferenceHelper::Event &event) +std::ostream& +operator<<(std::ostream& os, const LoraInterferenceHelper::Event& event) { - event.Print (os); + event.Print(os); - return os; + return os; } /**************************** @@ -114,309 +121,317 @@ operator<< (std::ostream &os, const LoraInterferenceHelper::Event &event) ****************************/ // This collision matrix can be used for comparisons with the performance of Aloha // systems, where collisions imply the loss of both packets. -double inf = std::numeric_limits::max (); -std::vector> LoraInterferenceHelper::collisionSnirAloha= { +double inf = std::numeric_limits::max(); +std::vector> LoraInterferenceHelper::collisionSnirAloha = { // 7 8 9 10 11 12 {inf, -inf, -inf, -inf, -inf, -inf}, // SF7 {-inf, inf, -inf, -inf, -inf, -inf}, // SF8 {-inf, -inf, inf, -inf, -inf, -inf}, // SF9 {-inf, -inf, -inf, inf, -inf, -inf}, // SF10 {-inf, -inf, -inf, -inf, inf, -inf}, // SF11 - {-inf, -inf, -inf, -inf, -inf, inf} // SF12 + {-inf, -inf, -inf, -inf, -inf, inf} // SF12 }; // LoRa Collision Matrix (Goursaud) // Values are inverted w.r.t. the paper since here we interpret this as an // _isolation_ matrix instead of a cochannel _rejection_ matrix like in // Goursaud's paper. - std::vector> LoraInterferenceHelper::collisionSnirGoursaud= { +std::vector> LoraInterferenceHelper::collisionSnirGoursaud = { // SF7 SF8 SF9 SF10 SF11 SF12 {6, -16, -18, -19, -19, -20}, // SF7 {-24, 6, -20, -22, -22, -22}, // SF8 {-27, -27, 6, -23, -25, -25}, // SF9 {-30, -30, -30, 6, -26, -28}, // SF10 {-33, -33, -33, -33, 6, -29}, // SF11 - {-36, -36, -36, -36, -36, 6} // SF12 + {-36, -36, -36, -36, -36, 6} // SF12 }; LoraInterferenceHelper::CollisionMatrix LoraInterferenceHelper::collisionMatrix = LoraInterferenceHelper::GOURSAUD; -NS_OBJECT_ENSURE_REGISTERED (LoraInterferenceHelper); +NS_OBJECT_ENSURE_REGISTERED(LoraInterferenceHelper); void -LoraInterferenceHelper::SetCollisionMatrix ( +LoraInterferenceHelper::SetCollisionMatrix( enum LoraInterferenceHelper::CollisionMatrix collisionMatrix) { - switch (collisionMatrix) + switch (collisionMatrix) { case LoraInterferenceHelper::ALOHA: - NS_LOG_DEBUG ("Setting the ALOHA collision matrix"); - m_collisionSnir = LoraInterferenceHelper::collisionSnirAloha; - break; + NS_LOG_DEBUG("Setting the ALOHA collision matrix"); + m_collisionSnir = LoraInterferenceHelper::collisionSnirAloha; + break; case LoraInterferenceHelper::GOURSAUD: - NS_LOG_DEBUG ("Setting the GOURSAUD collision matrix"); - m_collisionSnir = LoraInterferenceHelper::collisionSnirGoursaud; - break; + NS_LOG_DEBUG("Setting the GOURSAUD collision matrix"); + m_collisionSnir = LoraInterferenceHelper::collisionSnirGoursaud; + break; } } TypeId -LoraInterferenceHelper::GetTypeId (void) +LoraInterferenceHelper::GetTypeId(void) { - static TypeId tid = - TypeId ("ns3::LoraInterferenceHelper").SetParent ().SetGroupName ("lorawan"); + static TypeId tid = + TypeId("ns3::LoraInterferenceHelper").SetParent().SetGroupName("lorawan"); - return tid; + return tid; } - LoraInterferenceHelper::LoraInterferenceHelper () : m_collisionSnir(LoraInterferenceHelper::collisionSnirGoursaud) +LoraInterferenceHelper::LoraInterferenceHelper() + : m_collisionSnir(LoraInterferenceHelper::collisionSnirGoursaud) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - SetCollisionMatrix (collisionMatrix); + SetCollisionMatrix(collisionMatrix); } -LoraInterferenceHelper::~LoraInterferenceHelper () +LoraInterferenceHelper::~LoraInterferenceHelper() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -Time LoraInterferenceHelper::oldEventThreshold = Seconds (2); +Time LoraInterferenceHelper::oldEventThreshold = Seconds(2); Ptr -LoraInterferenceHelper::Add (Time duration, double rxPower, uint8_t spreadingFactor, - Ptr packet, double frequencyMHz) +LoraInterferenceHelper::Add(Time duration, + double rxPower, + uint8_t spreadingFactor, + Ptr packet, + double frequencyMHz) { - - NS_LOG_FUNCTION (this << duration.GetSeconds () << rxPower << unsigned(spreadingFactor) << packet - << frequencyMHz); - - // Create an event based on the parameters - Ptr event = Create ( - duration, rxPower, spreadingFactor, packet, frequencyMHz); - - // Add the event to the list - m_events.push_back (event); - - // Clean the event list - if (m_events.size () > 100) + NS_LOG_FUNCTION(this << duration.GetSeconds() << rxPower << unsigned(spreadingFactor) << packet + << frequencyMHz); + + // Create an event based on the parameters + Ptr event = + Create(duration, + rxPower, + spreadingFactor, + packet, + frequencyMHz); + + // Add the event to the list + m_events.push_back(event); + + // Clean the event list + if (m_events.size() > 100) { - CleanOldEvents (); + CleanOldEvents(); } - return event; + return event; } void -LoraInterferenceHelper::CleanOldEvents (void) +LoraInterferenceHelper::CleanOldEvents(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Cycle the events, and clean up if an event is old. - for (auto it = m_events.begin (); it != m_events.end ();) + // Cycle the events, and clean up if an event is old. + for (auto it = m_events.begin(); it != m_events.end();) { - if ((*it)->GetEndTime () + oldEventThreshold < Simulator::Now ()) + if ((*it)->GetEndTime() + oldEventThreshold < Simulator::Now()) { - it = m_events.erase (it); + it = m_events.erase(it); } - else + else { - it++; + it++; } } } std::list> -LoraInterferenceHelper::GetInterferers () +LoraInterferenceHelper::GetInterferers() { - return m_events; + return m_events; } void -LoraInterferenceHelper::PrintEvents (std::ostream &stream) +LoraInterferenceHelper::PrintEvents(std::ostream& stream) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - stream << "Currently registered events:" << std::endl; + stream << "Currently registered events:" << std::endl; - for (auto it = m_events.begin (); it != m_events.end (); it++) + for (auto it = m_events.begin(); it != m_events.end(); it++) { - (*it)->Print (stream); - stream << std::endl; + (*it)->Print(stream); + stream << std::endl; } } uint8_t -LoraInterferenceHelper::IsDestroyedByInterference (Ptr event) +LoraInterferenceHelper::IsDestroyedByInterference(Ptr event) { - NS_LOG_FUNCTION (this << event); + NS_LOG_FUNCTION(this << event); - NS_LOG_INFO ("Current number of events in LoraInterferenceHelper: " << m_events.size ()); + NS_LOG_INFO("Current number of events in LoraInterferenceHelper: " << m_events.size()); - // We want to see the interference affecting this event: cycle through events - // that overlap with this one and see whether it survives the interference or - // not. + // We want to see the interference affecting this event: cycle through events + // that overlap with this one and see whether it survives the interference or + // not. - // Gather information about the event - double rxPowerDbm = event->GetRxPowerdBm (); - uint8_t sf = event->GetSpreadingFactor (); - double frequency = event->GetFrequency (); + // Gather information about the event + double rxPowerDbm = event->GetRxPowerdBm(); + uint8_t sf = event->GetSpreadingFactor(); + double frequency = event->GetFrequency(); - // Handy information about the time frame when the packet was received - Time now = Simulator::Now (); - Time duration = event->GetDuration (); - Time packetStartTime = now - duration; - Time packetEndTime = now; + // Handy information about the time frame when the packet was received + Time now = Simulator::Now(); + Time duration = event->GetDuration(); + Time packetStartTime = now - duration; + Time packetEndTime = now; - // Get the list of interfering events - std::list>::iterator it; + // Get the list of interfering events + std::list>::iterator it; - // Energy for interferers of various SFs - std::vector cumulativeInterferenceEnergy (6, 0); + // Energy for interferers of various SFs + std::vector cumulativeInterferenceEnergy(6, 0); - // Cycle over the events - for (it = m_events.begin (); it != m_events.end ();) + // Cycle over the events + for (it = m_events.begin(); it != m_events.end();) { - // Pointer to the current interferer - Ptr interferer = *it; + // Pointer to the current interferer + Ptr interferer = *it; - // Only consider the current event if the channel is the same: we - // assume there's no interchannel interference. Also skip the current - // event if it's the same that we want to analyze. - if (!(interferer->GetFrequency () == frequency) || interferer == event) + // Only consider the current event if the channel is the same: we + // assume there's no interchannel interference. Also skip the current + // event if it's the same that we want to analyze. + if (!(interferer->GetFrequency() == frequency) || interferer == event) { - NS_LOG_DEBUG ("Different channel or same event"); - it++; - continue; // Continues from the first line inside the for cycle + NS_LOG_DEBUG("Different channel or same event"); + it++; + continue; // Continues from the first line inside the for cycle } - NS_LOG_DEBUG ("Interferer on same channel"); - - // Gather information about this interferer - uint8_t interfererSf = interferer->GetSpreadingFactor (); - double interfererPower = interferer->GetRxPowerdBm (); - Time interfererStartTime = interferer->GetStartTime (); - Time interfererEndTime = interferer->GetEndTime (); - - NS_LOG_INFO ("Found an interferer: sf = " << unsigned(interfererSf) - << ", power = " << interfererPower - << ", start time = " << interfererStartTime - << ", end time = " << interfererEndTime); - - // Compute the fraction of time the two events are overlapping - Time overlap = GetOverlapTime (event, interferer); - - NS_LOG_DEBUG ("The two events overlap for " << overlap.GetSeconds () << " s."); - - // Compute the equivalent energy of the interference - // Power [mW] = 10^(Power[dBm]/10) - // Power [W] = Power [mW] / 1000 - double interfererPowerW = pow (10, interfererPower / 10) / 1000; - // Energy [J] = Time [s] * Power [W] - double interferenceEnergy = overlap.GetSeconds () * interfererPowerW; - cumulativeInterferenceEnergy.at (unsigned(interfererSf) - 7) += interferenceEnergy; - NS_LOG_DEBUG ("Interferer power in W: " << interfererPowerW); - NS_LOG_DEBUG ("Interference energy: " << interferenceEnergy); - it++; + NS_LOG_DEBUG("Interferer on same channel"); + + // Gather information about this interferer + uint8_t interfererSf = interferer->GetSpreadingFactor(); + double interfererPower = interferer->GetRxPowerdBm(); + Time interfererStartTime = interferer->GetStartTime(); + Time interfererEndTime = interferer->GetEndTime(); + + NS_LOG_INFO("Found an interferer: sf = " << unsigned(interfererSf) + << ", power = " << interfererPower + << ", start time = " << interfererStartTime + << ", end time = " << interfererEndTime); + + // Compute the fraction of time the two events are overlapping + Time overlap = GetOverlapTime(event, interferer); + + NS_LOG_DEBUG("The two events overlap for " << overlap.GetSeconds() << " s."); + + // Compute the equivalent energy of the interference + // Power [mW] = 10^(Power[dBm]/10) + // Power [W] = Power [mW] / 1000 + double interfererPowerW = pow(10, interfererPower / 10) / 1000; + // Energy [J] = Time [s] * Power [W] + double interferenceEnergy = overlap.GetSeconds() * interfererPowerW; + cumulativeInterferenceEnergy.at(unsigned(interfererSf) - 7) += interferenceEnergy; + NS_LOG_DEBUG("Interferer power in W: " << interfererPowerW); + NS_LOG_DEBUG("Interference energy: " << interferenceEnergy); + it++; } - // For each SF, check if there was destructive interference - for (uint8_t currentSf = uint8_t (7); currentSf <= uint8_t (12); currentSf++) + // For each SF, check if there was destructive interference + for (uint8_t currentSf = uint8_t(7); currentSf <= uint8_t(12); currentSf++) { - NS_LOG_DEBUG ("Cumulative Interference Energy: " - << cumulativeInterferenceEnergy.at (unsigned(currentSf) - 7)); - - // Use the computed cumulativeInterferenceEnergy to determine whether the - // interference with this SF destroys the packet - double signalPowerW = pow (10, rxPowerDbm / 10) / 1000; - double signalEnergy = duration.GetSeconds () * signalPowerW; - NS_LOG_DEBUG ("Signal power in W: " << signalPowerW); - NS_LOG_DEBUG ("Signal energy: " << signalEnergy); - - // Check whether the packet survives the interference of this SF - double snirIsolation = m_collisionSnir[unsigned(sf) - 7][unsigned(currentSf) - 7]; - NS_LOG_DEBUG ("The needed isolation to survive is " << snirIsolation << " dB"); - double snir = - 10 * log10 (signalEnergy / cumulativeInterferenceEnergy.at (unsigned(currentSf) - 7)); - NS_LOG_DEBUG ("The current SNIR is " << snir << " dB"); - - if (snir >= snirIsolation) + NS_LOG_DEBUG("Cumulative Interference Energy: " + << cumulativeInterferenceEnergy.at(unsigned(currentSf) - 7)); + + // Use the computed cumulativeInterferenceEnergy to determine whether the + // interference with this SF destroys the packet + double signalPowerW = pow(10, rxPowerDbm / 10) / 1000; + double signalEnergy = duration.GetSeconds() * signalPowerW; + NS_LOG_DEBUG("Signal power in W: " << signalPowerW); + NS_LOG_DEBUG("Signal energy: " << signalEnergy); + + // Check whether the packet survives the interference of this SF + double snirIsolation = m_collisionSnir[unsigned(sf) - 7][unsigned(currentSf) - 7]; + NS_LOG_DEBUG("The needed isolation to survive is " << snirIsolation << " dB"); + double snir = + 10 * log10(signalEnergy / cumulativeInterferenceEnergy.at(unsigned(currentSf) - 7)); + NS_LOG_DEBUG("The current SNIR is " << snir << " dB"); + + if (snir >= snirIsolation) { - // Move on and check the rest of the interferers - NS_LOG_DEBUG ("Packet survived interference with SF " << currentSf); + // Move on and check the rest of the interferers + NS_LOG_DEBUG("Packet survived interference with SF " << currentSf); } - else + else { - NS_LOG_DEBUG ("Packet destroyed by interference with SF" << unsigned(currentSf)); + NS_LOG_DEBUG("Packet destroyed by interference with SF" << unsigned(currentSf)); - return currentSf; + return currentSf; } } - // If we get to here, it means that the packet survived all interference - NS_LOG_DEBUG ("Packet survived all interference"); + // If we get to here, it means that the packet survived all interference + NS_LOG_DEBUG("Packet survived all interference"); - // Since the packet was not destroyed, we return 0. - return uint8_t (0); + // Since the packet was not destroyed, we return 0. + return uint8_t(0); } void -LoraInterferenceHelper::ClearAllEvents (void) +LoraInterferenceHelper::ClearAllEvents(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_events.clear (); + m_events.clear(); } Time -LoraInterferenceHelper::GetOverlapTime (Ptr event1, - Ptr event2) +LoraInterferenceHelper::GetOverlapTime(Ptr event1, + Ptr event2) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Create the value we will return later - Time overlap; + // Create the value we will return later + Time overlap; - // Get handy values - Time s1 = event1->GetStartTime (); // Start times - Time s2 = event2->GetStartTime (); - Time e1 = event1->GetEndTime (); // End times - Time e2 = event2->GetEndTime (); + // Get handy values + Time s1 = event1->GetStartTime(); // Start times + Time s2 = event2->GetStartTime(); + Time e1 = event1->GetEndTime(); // End times + Time e2 = event2->GetEndTime(); - // Non-overlapping events - if (e1 <= s2 || e2 <= s1) + // Non-overlapping events + if (e1 <= s2 || e2 <= s1) { - overlap = Seconds (0); + overlap = Seconds(0); } - // event1 before event2 - else if (s1 < s2) + // event1 before event2 + else if (s1 < s2) { - if (e2 < e1) + if (e2 < e1) { - overlap = e2 - s2; + overlap = e2 - s2; } - else + else { - overlap = e1 - s2; + overlap = e1 - s2; } } - // event2 before event1 or they start at the same time (s1 = s2) - else + // event2 before event1 or they start at the same time (s1 = s2) + else { - if (e1 < e2) + if (e1 < e2) { - overlap = e1 - s1; + overlap = e1 - s1; } - else + else { - overlap = e2 - s1; + overlap = e2 - s1; } } - return overlap; + return overlap; } } // namespace lorawan } // namespace ns3 + /* ---------------------------------------------------------------------------- diff --git a/model/lora-interference-helper.h b/model/lora-interference-helper.h index 2cf3edb5d6..a732e1a2e1 100644 --- a/model/lora-interference-helper.h +++ b/model/lora-interference-helper.h @@ -21,17 +21,21 @@ #ifndef LORA_INTERFERENCE_HELPER_H #define LORA_INTERFERENCE_HELPER_H +#include "logical-lora-channel.h" + +#include "ns3/callback.h" #include "ns3/nstime.h" -#include "ns3/simulator.h" #include "ns3/object.h" -#include "ns3/traced-callback.h" -#include "ns3/callback.h" #include "ns3/packet.h" -#include "ns3/logical-lora-channel.h" +#include "ns3/simulator.h" +#include "ns3/traced-callback.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Helper for LoraPhy that manages interference calculations. @@ -42,189 +46,195 @@ namespace lorawan { */ class LoraInterferenceHelper { -public: - /** - * A class representing a signal in time. - * - * Used in LoraInterferenceHelper to keep track of which signals overlap and - * cause destructive interference. - */ - class Event : public SimpleRefCount - { - public: - Event (Time duration, double rxPowerdBm, uint8_t spreadingFactor, Ptr packet, - double frequencyMHz); - ~Event (); - /** - * Get the duration of the event. + * A class representing a signal in time. + * + * Used in LoraInterferenceHelper to keep track of which signals overlap and + * cause destructive interference. */ - Time GetDuration (void) const; + class Event : public SimpleRefCount + { + public: + Event(Time duration, + double rxPowerdBm, + uint8_t spreadingFactor, + Ptr packet, + double frequencyMHz); + ~Event(); + + /** + * Get the duration of the event. + */ + Time GetDuration(void) const; + + /** + * Get the starting time of the event. + */ + Time GetStartTime(void) const; + + /** + * Get the ending time of the event. + */ + Time GetEndTime(void) const; + + /** + * Get the power of the event. + */ + double GetRxPowerdBm(void) const; + + /** + * Get the spreading factor used by this signal. + */ + uint8_t GetSpreadingFactor(void) const; + + /** + * Get the packet this event was generated for. + */ + Ptr GetPacket(void) const; + + /** + * Get the frequency this event was on. + */ + double GetFrequency(void) const; + + /** + * Print the current event in a human readable form. + */ + void Print(std::ostream& stream) const; + + private: + /** + * The time this signal begins (at the device). + */ + Time m_startTime; + + /** + * The time this signal ends (at the device). + */ + Time m_endTime; + + /** + * The spreading factor of this signal. + */ + uint8_t m_sf; + + /** + * The power of this event in dBm (at the device). + */ + double m_rxPowerdBm; + + /** + * The packet this event was generated for. + */ + Ptr m_packet; + + /** + * The frequency this event was on. + */ + double m_frequencyMHz; + }; + + enum CollisionMatrix + { + GOURSAUD, + ALOHA, + }; + + static TypeId GetTypeId(void); + + LoraInterferenceHelper(); + virtual ~LoraInterferenceHelper(); /** - * Get the starting time of the event. + * Add an event to the InterferenceHelper + * + * \param duration the duration of the packet. + * \param rxPower the received power in dBm. + * \param spreadingFactor the spreading factor used by the transmission. + * \param packet The packet carried by this transmission. + * \param frequencyMHz The frequency this event was sent at. + * + * \return the newly created event */ - Time GetStartTime (void) const; + Ptr Add(Time duration, + double rxPower, + uint8_t spreadingFactor, + Ptr packet, + double frequencyMHz); /** - * Get the ending time of the event. + * Get a list of the interferers currently registered at this + * InterferenceHelper. */ - Time GetEndTime (void) const; + std::list> GetInterferers(); /** - * Get the power of the event. + * Print the events that are saved in this helper in a human readable format. */ - double GetRxPowerdBm (void) const; + void PrintEvents(std::ostream& stream); /** - * Get the spreading factor used by this signal. - */ - uint8_t GetSpreadingFactor (void) const; + * Determine whether the event was destroyed by interference or not. This is + * the method where the SNIR tables come into play and the computations + * regarding power are performed. - /** - * Get the packet this event was generated for. + * \param event The event for which to check the outcome. + * \return The sf of the packets that caused the loss, or 0 if there was no + * loss. */ - Ptr GetPacket (void) const; + uint8_t IsDestroyedByInterference(Ptr event); /** - * Get the frequency this event was on. + * Compute the time duration in which two given events are overlapping. + * + * \param event1 The first event + * \param event2 The second event + * + * \return The overlap time */ - double GetFrequency (void) const; + Time GetOverlapTime(Ptr event1, + Ptr event2); /** - * Print the current event in a human readable form. + * Delete all events in the LoraInterferenceHelper. */ - void Print (std::ostream &stream) const; + void ClearAllEvents(void); - private: /** - * The time this signal begins (at the device). + * Delete old events in this LoraInterferenceHelper. */ - Time m_startTime; + void CleanOldEvents(void); - /** - * The time this signal ends (at the device). - */ - Time m_endTime; + static CollisionMatrix collisionMatrix; - /** - * The spreading factor of this signal. - */ - uint8_t m_sf; + static std::vector> collisionSnirAloha; + static std::vector> collisionSnirGoursaud; + + private: + void SetCollisionMatrix(enum CollisionMatrix collisionMatrix); + + std::vector> m_collisionSnir; /** - * The power of this event in dBm (at the device). + * A list of the events this LoraInterferenceHelper is keeping track of. */ - double m_rxPowerdBm; + std::list> m_events; /** - * The packet this event was generated for. + * The matrix containing information about how packets survive interference. */ - Ptr m_packet; - /** - * The frequency this event was on. + * The threshold after which an event is considered old and removed from the + * list. */ - double m_frequencyMHz; - }; - - enum CollisionMatrix { - GOURSAUD, - ALOHA, - }; - - static TypeId GetTypeId (void); - - LoraInterferenceHelper (); - virtual ~LoraInterferenceHelper (); - - /** - * Add an event to the InterferenceHelper - * - * \param duration the duration of the packet. - * \param rxPower the received power in dBm. - * \param spreadingFactor the spreading factor used by the transmission. - * \param packet The packet carried by this transmission. - * \param frequencyMHz The frequency this event was sent at. - * - * \return the newly created event - */ - Ptr Add (Time duration, double rxPower, uint8_t spreadingFactor, - Ptr packet, double frequencyMHz); - - /** - * Get a list of the interferers currently registered at this - * InterferenceHelper. - */ - std::list> GetInterferers (); - - /** - * Print the events that are saved in this helper in a human readable format. - */ - void PrintEvents (std::ostream &stream); - - /** - * Determine whether the event was destroyed by interference or not. This is - * the method where the SNIR tables come into play and the computations - * regarding power are performed. - - * \param event The event for which to check the outcome. - * \return The sf of the packets that caused the loss, or 0 if there was no - * loss. - */ - uint8_t IsDestroyedByInterference (Ptr event); - - /** - * Compute the time duration in which two given events are overlapping. - * - * \param event1 The first event - * \param event2 The second event - * - * \return The overlap time - */ - Time GetOverlapTime (Ptr event1, - Ptr event2); - - /** - * Delete all events in the LoraInterferenceHelper. - */ - void ClearAllEvents (void); - - /** - * Delete old events in this LoraInterferenceHelper. - */ - void CleanOldEvents (void); - - static CollisionMatrix collisionMatrix; - - static std::vector> collisionSnirAloha; - static std::vector> collisionSnirGoursaud; - -private: - void SetCollisionMatrix (enum CollisionMatrix collisionMatrix); - - std::vector> m_collisionSnir; - - /** - * A list of the events this LoraInterferenceHelper is keeping track of. - */ - std::list> m_events; - - /** - * The matrix containing information about how packets survive interference. - */ - /** - * The threshold after which an event is considered old and removed from the - * list. - */ - static Time oldEventThreshold; + static Time oldEventThreshold; }; /** * Allow easy logging of LoraInterferenceHelper Events */ -std::ostream &operator<< (std::ostream &os, const LoraInterferenceHelper::Event &event); +std::ostream& operator<<(std::ostream& os, const LoraInterferenceHelper::Event& event); } // namespace lorawan } // namespace ns3 diff --git a/model/lora-net-device.cc b/model/lora-net-device.cc index 4fce73f71e..a0e97408dd 100644 --- a/model/lora-net-device.cc +++ b/model/lora-net-device.cc @@ -18,114 +18,119 @@ * Author: Davide Magrin */ -#include "ns3/lora-net-device.h" -#include "ns3/pointer.h" -#include "ns3/node.h" -#include "ns3/log.h" +#include "lora-net-device.h" + #include "ns3/abort.h" +#include "ns3/log.h" +#include "ns3/node.h" +#include "ns3/pointer.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraNetDevice"); +NS_LOG_COMPONENT_DEFINE("LoraNetDevice"); -NS_OBJECT_ENSURE_REGISTERED (LoraNetDevice); +NS_OBJECT_ENSURE_REGISTERED(LoraNetDevice); TypeId -LoraNetDevice::GetTypeId (void) +LoraNetDevice::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LoraNetDevice") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan") - .AddAttribute ("Channel", "The channel attached to this device", - PointerValue (), - MakePointerAccessor (&LoraNetDevice::DoGetChannel), - MakePointerChecker ()) - .AddAttribute ("Phy", "The PHY layer attached to this device.", - PointerValue (), - MakePointerAccessor (&LoraNetDevice::GetPhy, - &LoraNetDevice::SetPhy), - MakePointerChecker ()) - .AddAttribute ("Mac", "The MAC layer attached to this device.", - PointerValue (), - MakePointerAccessor (&LoraNetDevice::GetMac, - &LoraNetDevice::SetMac), - MakePointerChecker ()); - return tid; + static TypeId tid = + TypeId("ns3::LoraNetDevice") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan") + .AddAttribute("Channel", + "The channel attached to this device", + PointerValue(), + MakePointerAccessor(&LoraNetDevice::DoGetChannel), + MakePointerChecker()) + .AddAttribute("Phy", + "The PHY layer attached to this device.", + PointerValue(), + MakePointerAccessor(&LoraNetDevice::GetPhy, &LoraNetDevice::SetPhy), + MakePointerChecker()) + .AddAttribute("Mac", + "The MAC layer attached to this device.", + PointerValue(), + MakePointerAccessor(&LoraNetDevice::GetMac, &LoraNetDevice::SetMac), + MakePointerChecker()); + return tid; } -LoraNetDevice::LoraNetDevice () : - m_node (0), - m_phy (0), - m_mac (0), - m_configComplete (0) +LoraNetDevice::LoraNetDevice() + : m_node(0), + m_phy(0), + m_mac(0), + m_configComplete(0) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -LoraNetDevice::~LoraNetDevice () +LoraNetDevice::~LoraNetDevice() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -LoraNetDevice::SetMac (Ptr mac) +LoraNetDevice::SetMac(Ptr mac) { - m_mac = mac; + m_mac = mac; } Ptr -LoraNetDevice::GetMac (void) const +LoraNetDevice::GetMac(void) const { - return m_mac; + return m_mac; } void -LoraNetDevice::SetPhy (Ptr phy) +LoraNetDevice::SetPhy(Ptr phy) { - m_phy = phy; + m_phy = phy; } Ptr -LoraNetDevice::GetPhy (void) const +LoraNetDevice::GetPhy(void) const { - return m_phy; + return m_phy; } void -LoraNetDevice::CompleteConfig (void) +LoraNetDevice::CompleteConfig(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Verify we have all the necessary pieces - if (!m_mac || !m_phy || !m_node || m_configComplete) + // Verify we have all the necessary pieces + if (!m_mac || !m_phy || !m_node || m_configComplete) { - return; + return; } - m_mac->SetPhy (m_phy); - m_configComplete = true; + m_mac->SetPhy(m_phy); + m_configComplete = true; } void -LoraNetDevice::Send (Ptr packet) +LoraNetDevice::Send(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // Send the packet to the MAC layer, if it exists - NS_ASSERT (m_mac); - m_mac->Send (packet); + // Send the packet to the MAC layer, if it exists + NS_ASSERT(m_mac); + m_mac->Send(packet); } void -LoraNetDevice::Receive (Ptr packet) +LoraNetDevice::Receive(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // Fill protocol and address with empty stuff - NS_LOG_DEBUG ("Calling receiveCallback"); - m_receiveCallback (this, packet, 0, Address ()); + // Fill protocol and address with empty stuff + NS_LOG_DEBUG("Calling receiveCallback"); + m_receiveCallback(this, packet, 0, Address()); } /****************************************** @@ -133,201 +138,202 @@ LoraNetDevice::Receive (Ptr packet) ******************************************/ Ptr -LoraNetDevice::GetChannel (void) const +LoraNetDevice::GetChannel(void) const { - NS_LOG_FUNCTION (this); - return m_phy->GetChannel (); + NS_LOG_FUNCTION(this); + return m_phy->GetChannel(); } Ptr -LoraNetDevice::DoGetChannel (void) const +LoraNetDevice::DoGetChannel(void) const { - NS_LOG_FUNCTION (this); - return m_phy->GetChannel (); + NS_LOG_FUNCTION(this); + return m_phy->GetChannel(); } void -LoraNetDevice::SetIfIndex (const uint32_t index) +LoraNetDevice::SetIfIndex(const uint32_t index) { - NS_LOG_FUNCTION (this << index); + NS_LOG_FUNCTION(this << index); } uint32_t -LoraNetDevice::GetIfIndex (void) const +LoraNetDevice::GetIfIndex(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return 0; + return 0; } void -LoraNetDevice::SetAddress (Address address) +LoraNetDevice::SetAddress(Address address) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } Address -LoraNetDevice::GetAddress (void) const +LoraNetDevice::GetAddress(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return Address (); + return Address(); } bool -LoraNetDevice::SetMtu (const uint16_t mtu) +LoraNetDevice::SetMtu(const uint16_t mtu) { - NS_ABORT_MSG ("Unsupported"); + NS_ABORT_MSG("Unsupported"); - return false; + return false; } uint16_t -LoraNetDevice::GetMtu (void) const +LoraNetDevice::GetMtu(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return 0; + return 0; } bool -LoraNetDevice::IsLinkUp (void) const +LoraNetDevice::IsLinkUp(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_phy != nullptr; + return m_phy != nullptr; } void -LoraNetDevice::AddLinkChangeCallback (Callback callback) +LoraNetDevice::AddLinkChangeCallback(Callback callback) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } bool -LoraNetDevice::IsBroadcast (void) const +LoraNetDevice::IsBroadcast(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return true; + return true; } Address -LoraNetDevice::GetBroadcast (void) const +LoraNetDevice::GetBroadcast(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return Address (); + return Address(); } bool -LoraNetDevice::IsMulticast (void) const +LoraNetDevice::IsMulticast(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return true; + return true; } Address -LoraNetDevice::GetMulticast (Ipv4Address multicastGroup) const +LoraNetDevice::GetMulticast(Ipv4Address multicastGroup) const { - NS_ABORT_MSG ("Unsupported"); + NS_ABORT_MSG("Unsupported"); - return Address (); + return Address(); } Address -LoraNetDevice::GetMulticast (Ipv6Address addr) const +LoraNetDevice::GetMulticast(Ipv6Address addr) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return Address (); + return Address(); } bool -LoraNetDevice::IsBridge (void) const +LoraNetDevice::IsBridge(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return false; + return false; } bool -LoraNetDevice::IsPointToPoint (void) const +LoraNetDevice::IsPointToPoint(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return false; + return false; } bool -LoraNetDevice::Send (Ptr packet, const Address& dest, - uint16_t protocolNumber) +LoraNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) { - NS_LOG_FUNCTION (this << packet << dest << protocolNumber); + NS_LOG_FUNCTION(this << packet << dest << protocolNumber); - // Fallback to the vanilla Send method - Send (packet); + // Fallback to the vanilla Send method + Send(packet); - return true; + return true; } bool -LoraNetDevice::SendFrom (Ptr packet, const Address& source, - const Address& dest, uint16_t protocolNumber) +LoraNetDevice::SendFrom(Ptr packet, + const Address& source, + const Address& dest, + uint16_t protocolNumber) { - NS_ABORT_MSG ("Unsupported"); + NS_ABORT_MSG("Unsupported"); - return false; + return false; } Ptr -LoraNetDevice::GetNode (void) const +LoraNetDevice::GetNode(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_node; + return m_node; } void -LoraNetDevice::SetNode (Ptr node) +LoraNetDevice::SetNode(Ptr node) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_node = node; - CompleteConfig (); + m_node = node; + CompleteConfig(); } bool -LoraNetDevice::NeedsArp (void) const +LoraNetDevice::NeedsArp(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return true; + return true; } void -LoraNetDevice::SetReceiveCallback (ReceiveCallback cb) +LoraNetDevice::SetReceiveCallback(ReceiveCallback cb) { - NS_LOG_FUNCTION_NOARGS (); - m_receiveCallback = cb; + NS_LOG_FUNCTION_NOARGS(); + m_receiveCallback = cb; } void -LoraNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) +LoraNetDevice::SetPromiscReceiveCallback(PromiscReceiveCallback cb) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } bool -LoraNetDevice::SupportsSendFrom (void) const +LoraNetDevice::SupportsSendFrom(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return false; + return false; } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-net-device.h b/model/lora-net-device.h index 0e2b0b6a7f..8f777f6240 100644 --- a/model/lora-net-device.h +++ b/model/lora-net-device.h @@ -21,13 +21,16 @@ #ifndef LORA_NET_DEVICE_H #define LORA_NET_DEVICE_H +#include "lora-channel.h" +#include "lora-phy.h" +#include "lorawan-mac.h" + #include "ns3/net-device.h" -#include "ns3/lora-channel.h" -#include "ns3/lora-phy.h" -#include "ns3/lorawan-mac.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; class LoraPhy; @@ -43,125 +46,128 @@ class LorawanMac; */ class LoraNetDevice : public NetDevice { -public: - static TypeId GetTypeId (void); - - // Constructor and destructor - LoraNetDevice (); - virtual ~LoraNetDevice (); - - /** - * Set which LorawanMac instance is linked to this device. - * - * \param mac the mac layer to use. - */ - void SetMac (Ptr mac); - - /** - * Set which LoraPhy instance is linked to this device. - * - * \param phy the phy layer to use. - */ - void SetPhy (Ptr phy); - - /** - * Get the LorawanMac instance that is linked to this NetDevice. - * - * \return the mac we are currently using. - */ - Ptr GetMac (void) const; - - /** - * Get the LoraPhy instance that is linked to this NetDevice. - * - * \return the phy we are currently using. - */ - Ptr GetPhy (void) const; - - /** - * Send a packet through the LoRaWAN stack. - * - * \param packet The packet to send. - */ - void Send (Ptr packet); - - /** - * This function is implemented to achieve compliance with the NetDevice - * interface. Note that the dest and protocolNumber args are ignored. - */ - bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); - - /** - * Callback the Mac layer calls whenever a packet arrives and needs to be - * forwarded up the stack. - * - * \param packet The packet that was received. - */ - void Receive (Ptr packet); - - // From class NetDevice. Some of these have little meaning for a LoRaWAN - // network device (since, for instance, IP is not used in the standard) - virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); - virtual Ptr GetChannel (void) const; - virtual void SetNode (Ptr node); - virtual Ptr GetNode (void) const; - - virtual void SetIfIndex (const uint32_t index); - virtual uint32_t GetIfIndex (void) const; - virtual void SetAddress (Address address); - virtual Address GetAddress (void) const; - virtual bool SetMtu (const uint16_t mtu); - virtual uint16_t GetMtu (void) const; - virtual bool IsLinkUp (void) const; - virtual void AddLinkChangeCallback (Callback callback); - virtual bool IsBroadcast (void) const; - virtual Address GetBroadcast (void) const; - virtual bool IsMulticast (void) const; - virtual Address GetMulticast (Ipv4Address multicastGroup) const; - virtual Address GetMulticast (Ipv6Address addr) const; - virtual bool IsBridge (void) const; - virtual bool IsPointToPoint (void) const; - virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); - virtual bool NeedsArp (void) const; - virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); - virtual bool SupportsSendFrom (void) const; - -protected: - /** - * Receive a packet from the lower layer and pass the - * packet up the stack. - * - * \param packet The packet we need to forward. - * \param from The from address. - * \param to The to address. - */ - void ForwardUp (Ptr packet, Mac48Address from, Mac48Address to); - -private: - /** - * Return the LoraChannel this device is connected to. - */ - Ptr DoGetChannel (void) const; - - /** - * Complete the configuration of this LoRa device by connecting all lower - * components (PHY, MAC, Channel) together. - */ - void CompleteConfig (void); - - // Member variables - Ptr m_node; //!< The Node this NetDevice is connected to. - Ptr m_phy; //!< The LoraPhy this NetDevice is connected to. - Ptr m_mac; //!< The LorawanMac this NetDevice is connected to. - bool m_configComplete; //!< Whether the configuration was already completed. - - /** - * Upper layer callback used for notification of new data packet arrivals. - */ - NetDevice::ReceiveCallback m_receiveCallback; + public: + static TypeId GetTypeId(void); + + // Constructor and destructor + LoraNetDevice(); + virtual ~LoraNetDevice(); + + /** + * Set which LorawanMac instance is linked to this device. + * + * \param mac the mac layer to use. + */ + void SetMac(Ptr mac); + + /** + * Set which LoraPhy instance is linked to this device. + * + * \param phy the phy layer to use. + */ + void SetPhy(Ptr phy); + + /** + * Get the LorawanMac instance that is linked to this NetDevice. + * + * \return the mac we are currently using. + */ + Ptr GetMac(void) const; + + /** + * Get the LoraPhy instance that is linked to this NetDevice. + * + * \return the phy we are currently using. + */ + Ptr GetPhy(void) const; + + /** + * Send a packet through the LoRaWAN stack. + * + * \param packet The packet to send. + */ + void Send(Ptr packet); + + /** + * This function is implemented to achieve compliance with the NetDevice + * interface. Note that the dest and protocolNumber args are ignored. + */ + bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber); + + /** + * Callback the Mac layer calls whenever a packet arrives and needs to be + * forwarded up the stack. + * + * \param packet The packet that was received. + */ + void Receive(Ptr packet); + + // From class NetDevice. Some of these have little meaning for a LoRaWAN + // network device (since, for instance, IP is not used in the standard) + virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb); + virtual Ptr GetChannel(void) const; + virtual void SetNode(Ptr node); + virtual Ptr GetNode(void) const; + + virtual void SetIfIndex(const uint32_t index); + virtual uint32_t GetIfIndex(void) const; + virtual void SetAddress(Address address); + virtual Address GetAddress(void) const; + virtual bool SetMtu(const uint16_t mtu); + virtual uint16_t GetMtu(void) const; + virtual bool IsLinkUp(void) const; + virtual void AddLinkChangeCallback(Callback callback); + virtual bool IsBroadcast(void) const; + virtual Address GetBroadcast(void) const; + virtual bool IsMulticast(void) const; + virtual Address GetMulticast(Ipv4Address multicastGroup) const; + virtual Address GetMulticast(Ipv6Address addr) const; + virtual bool IsBridge(void) const; + virtual bool IsPointToPoint(void) const; + virtual bool SendFrom(Ptr packet, + const Address& source, + const Address& dest, + uint16_t protocolNumber); + virtual bool NeedsArp(void) const; + virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb); + virtual bool SupportsSendFrom(void) const; + + protected: + /** + * Receive a packet from the lower layer and pass the + * packet up the stack. + * + * \param packet The packet we need to forward. + * \param from The from address. + * \param to The to address. + */ + void ForwardUp(Ptr packet, Mac48Address from, Mac48Address to); + + private: + /** + * Return the LoraChannel this device is connected to. + */ + Ptr DoGetChannel(void) const; + + /** + * Complete the configuration of this LoRa device by connecting all lower + * components (PHY, MAC, Channel) together. + */ + void CompleteConfig(void); + + // Member variables + Ptr m_node; //!< The Node this NetDevice is connected to. + Ptr m_phy; //!< The LoraPhy this NetDevice is connected to. + Ptr m_mac; //!< The LorawanMac this NetDevice is connected to. + bool m_configComplete; //!< Whether the configuration was already completed. + + /** + * Upper layer callback used for notification of new data packet arrivals. + */ + NetDevice::ReceiveCallback m_receiveCallback; }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_NET_DEVICE_H */ diff --git a/model/lora-phy.cc b/model/lora-phy.cc index e8b2b03f19..ecda251d7b 100644 --- a/model/lora-phy.cc +++ b/model/lora-phy.cc @@ -18,206 +18,206 @@ * Author: Davide Magrin */ -#include "ns3/lora-phy.h" +#include "lora-phy.h" + #include "ns3/log.h" #include "ns3/simulator.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraPhy"); +NS_LOG_COMPONENT_DEFINE("LoraPhy"); -NS_OBJECT_ENSURE_REGISTERED (LoraPhy); +NS_OBJECT_ENSURE_REGISTERED(LoraPhy); TypeId -LoraPhy::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::LoraPhy") - .SetParent () - .SetGroupName ("lorawan") - .AddTraceSource ("StartSending", - "Trace source indicating the PHY layer" - "has begun the sending process for a packet", - MakeTraceSourceAccessor (&LoraPhy::m_startSending), - "ns3::Packet::TracedCallback") - .AddTraceSource ("PhyRxBegin", - "Trace source indicating a packet " - "is now being received from the channel medium " - "by the device", - MakeTraceSourceAccessor (&LoraPhy::m_phyRxBeginTrace), - "ns3::Packet::TracedCallback") - .AddTraceSource ("PhyRxEnd", - "Trace source indicating the PHY has finished " - "the reception process for a packet", - MakeTraceSourceAccessor (&LoraPhy::m_phyRxEndTrace), - "ns3::Packet::TracedCallback") - .AddTraceSource ("ReceivedPacket", - "Trace source indicating a packet " - "was correctly received", - MakeTraceSourceAccessor - (&LoraPhy::m_successfullyReceivedPacket), - "ns3::Packet::TracedCallback") - .AddTraceSource ("LostPacketBecauseInterference", - "Trace source indicating a packet " - "could not be correctly decoded because of interfering" - "signals", - MakeTraceSourceAccessor (&LoraPhy::m_interferedPacket), - "ns3::Packet::TracedCallback") - .AddTraceSource ("LostPacketBecauseUnderSensitivity", - "Trace source indicating a packet " - "could not be correctly received because" - "its received power is below the sensitivity of the receiver", - MakeTraceSourceAccessor (&LoraPhy::m_underSensitivity), - "ns3::Packet::TracedCallback"); - return tid; -} - -LoraPhy::LoraPhy () +LoraPhy::GetTypeId(void) +{ + static TypeId tid = + TypeId("ns3::LoraPhy") + .SetParent() + .SetGroupName("lorawan") + .AddTraceSource("StartSending", + "Trace source indicating the PHY layer" + "has begun the sending process for a packet", + MakeTraceSourceAccessor(&LoraPhy::m_startSending), + "ns3::Packet::TracedCallback") + .AddTraceSource("PhyRxBegin", + "Trace source indicating a packet " + "is now being received from the channel medium " + "by the device", + MakeTraceSourceAccessor(&LoraPhy::m_phyRxBeginTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource("PhyRxEnd", + "Trace source indicating the PHY has finished " + "the reception process for a packet", + MakeTraceSourceAccessor(&LoraPhy::m_phyRxEndTrace), + "ns3::Packet::TracedCallback") + .AddTraceSource("ReceivedPacket", + "Trace source indicating a packet " + "was correctly received", + MakeTraceSourceAccessor(&LoraPhy::m_successfullyReceivedPacket), + "ns3::Packet::TracedCallback") + .AddTraceSource("LostPacketBecauseInterference", + "Trace source indicating a packet " + "could not be correctly decoded because of interfering" + "signals", + MakeTraceSourceAccessor(&LoraPhy::m_interferedPacket), + "ns3::Packet::TracedCallback") + .AddTraceSource("LostPacketBecauseUnderSensitivity", + "Trace source indicating a packet " + "could not be correctly received because" + "its received power is below the sensitivity of the receiver", + MakeTraceSourceAccessor(&LoraPhy::m_underSensitivity), + "ns3::Packet::TracedCallback"); + return tid; +} + +LoraPhy::LoraPhy() { } -LoraPhy::~LoraPhy () +LoraPhy::~LoraPhy() { } Ptr -LoraPhy::GetDevice (void) const +LoraPhy::GetDevice(void) const { - return m_device; + return m_device; } void -LoraPhy::SetDevice (Ptr device) +LoraPhy::SetDevice(Ptr device) { - NS_LOG_FUNCTION (this << device); + NS_LOG_FUNCTION(this << device); - m_device = device; + m_device = device; } Ptr -LoraPhy::GetChannel (void) const +LoraPhy::GetChannel(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_channel; + return m_channel; } Ptr -LoraPhy::GetMobility (void) +LoraPhy::GetMobility(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // If there is a mobility model associated to this PHY, take the mobility from - // there - if (m_mobility) + // If there is a mobility model associated to this PHY, take the mobility from + // there + if (m_mobility) { - return m_mobility; + return m_mobility; } - else // Else, take it from the node + else // Else, take it from the node { - return m_device->GetNode ()->GetObject (); + return m_device->GetNode()->GetObject(); } } void -LoraPhy::SetMobility (Ptr mobility) +LoraPhy::SetMobility(Ptr mobility) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - m_mobility = mobility; + m_mobility = mobility; } void -LoraPhy::SetChannel (Ptr channel) +LoraPhy::SetChannel(Ptr channel) { - NS_LOG_FUNCTION (this << channel); + NS_LOG_FUNCTION(this << channel); - m_channel = channel; + m_channel = channel; } void -LoraPhy::SetReceiveOkCallback (RxOkCallback callback) +LoraPhy::SetReceiveOkCallback(RxOkCallback callback) { - m_rxOkCallback = callback; + m_rxOkCallback = callback; } void -LoraPhy::SetReceiveFailedCallback (RxFailedCallback callback) +LoraPhy::SetReceiveFailedCallback(RxFailedCallback callback) { - m_rxFailedCallback = callback; + m_rxFailedCallback = callback; } void -LoraPhy::SetTxFinishedCallback (TxFinishedCallback callback) +LoraPhy::SetTxFinishedCallback(TxFinishedCallback callback) { - m_txFinishedCallback = callback; + m_txFinishedCallback = callback; } Time -LoraPhy::GetTSym (LoraTxParameters txParams) +LoraPhy::GetTSym(LoraTxParameters txParams) { - return Seconds (pow (2, int (txParams.sf)) / (txParams.bandwidthHz)); + return Seconds(pow(2, int(txParams.sf)) / (txParams.bandwidthHz)); } Time -LoraPhy::GetOnAirTime (Ptr packet, LoraTxParameters txParams) +LoraPhy::GetOnAirTime(Ptr packet, LoraTxParameters txParams) { + NS_LOG_FUNCTION(packet << txParams); - NS_LOG_FUNCTION (packet << txParams); - - // The contents of this function are based on [1]. - // [1] SX1272 LoRa modem designer's guide. + // The contents of this function are based on [1]. + // [1] SX1272 LoRa modem designer's guide. - // Compute the symbol duration - // Bandwidth is in Hz - double tSym = GetTSym(txParams).GetSeconds(); + // Compute the symbol duration + // Bandwidth is in Hz + double tSym = GetTSym(txParams).GetSeconds(); - // Compute the preamble duration - double tPreamble = (double(txParams.nPreamble) + 4.25) * tSym; + // Compute the preamble duration + double tPreamble = (double(txParams.nPreamble) + 4.25) * tSym; - // Payload size - uint32_t pl = packet->GetSize (); // Size in bytes - NS_LOG_DEBUG ("Packet of size " << pl << " bytes"); + // Payload size + uint32_t pl = packet->GetSize(); // Size in bytes + NS_LOG_DEBUG("Packet of size " << pl << " bytes"); - // This step is needed since the formula deals with double values. - // de = 1 when the low data rate optimization is enabled, 0 otherwise - // h = 1 when header is implicit, 0 otherwise - double de = txParams.lowDataRateOptimizationEnabled ? 1 : 0; - double h = txParams.headerDisabled ? 1 : 0; - double crc = txParams.crcEnabled ? 1 : 0; + // This step is needed since the formula deals with double values. + // de = 1 when the low data rate optimization is enabled, 0 otherwise + // h = 1 when header is implicit, 0 otherwise + double de = txParams.lowDataRateOptimizationEnabled ? 1 : 0; + double h = txParams.headerDisabled ? 1 : 0; + double crc = txParams.crcEnabled ? 1 : 0; - // num and den refer to numerator and denominator of the time on air formula - double num = 8 * pl - 4 * txParams.sf + 28 + 16 * crc - 20 * h; - double den = 4 * (txParams.sf - 2 * de); - double payloadSymbNb = 8 + std::max (std::ceil (num / den) * - (txParams.codingRate + 4), double(0)); + // num and den refer to numerator and denominator of the time on air formula + double num = 8 * pl - 4 * txParams.sf + 28 + 16 * crc - 20 * h; + double den = 4 * (txParams.sf - 2 * de); + double payloadSymbNb = + 8 + std::max(std::ceil(num / den) * (txParams.codingRate + 4), double(0)); - // Time to transmit the payload - double tPayload = payloadSymbNb * tSym; + // Time to transmit the payload + double tPayload = payloadSymbNb * tSym; - NS_LOG_DEBUG ("Time computation: num = " << num << ", den = " << den << - ", payloadSymbNb = " << payloadSymbNb << ", tSym = " << tSym); - NS_LOG_DEBUG ("tPreamble = " << tPreamble); - NS_LOG_DEBUG ("tPayload = " << tPayload); - NS_LOG_DEBUG ("Total time = " << tPreamble + tPayload); + NS_LOG_DEBUG("Time computation: num = " << num << ", den = " << den << ", payloadSymbNb = " + << payloadSymbNb << ", tSym = " << tSym); + NS_LOG_DEBUG("tPreamble = " << tPreamble); + NS_LOG_DEBUG("tPayload = " << tPayload); + NS_LOG_DEBUG("Total time = " << tPreamble + tPayload); - // Compute and return the total packet on-air time - return Seconds (tPreamble + tPayload); + // Compute and return the total packet on-air time + return Seconds(tPreamble + tPayload); } -std::ostream &operator << (std::ostream &os, const LoraTxParameters ¶ms) +std::ostream& +operator<<(std::ostream& os, const LoraTxParameters& params) { - os << "SF: " << unsigned(params.sf) << - ", headerDisabled: " << params.headerDisabled << - ", codingRate: " << unsigned(params.codingRate) << - ", bandwidthHz: " << params.bandwidthHz << - ", nPreamble: " << params.nPreamble << - ", crcEnabled: " << params.crcEnabled << - ", lowDataRateOptimizationEnabled: " << params.lowDataRateOptimizationEnabled << - ")"; + os << "SF: " << unsigned(params.sf) << ", headerDisabled: " << params.headerDisabled + << ", codingRate: " << unsigned(params.codingRate) << ", bandwidthHz: " << params.bandwidthHz + << ", nPreamble: " << params.nPreamble << ", crcEnabled: " << params.crcEnabled + << ", lowDataRateOptimizationEnabled: " << params.lowDataRateOptimizationEnabled << ")"; - return os; -} -} + return os; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-phy.h b/model/lora-phy.h index 60bf21a786..46395ff1c3 100644 --- a/model/lora-phy.h +++ b/model/lora-phy.h @@ -21,19 +21,22 @@ #ifndef LORA_PHY_H #define LORA_PHY_H -#include "ns3/object.h" +#include "lora-channel.h" +#include "lora-interference-helper.h" + #include "ns3/callback.h" -#include "ns3/net-device.h" -#include "ns3/nstime.h" #include "ns3/mobility-model.h" -#include "ns3/node.h" -#include "ns3/lora-channel.h" #include "ns3/net-device.h" -#include "ns3/lora-interference-helper.h" +#include "ns3/node.h" +#include "ns3/nstime.h" +#include "ns3/object.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; @@ -43,19 +46,19 @@ class LoraChannel; */ struct LoraTxParameters { - uint8_t sf = 7; //!< Spreading Factor - bool headerDisabled = 0; //!< Whether to use implicit header mode - uint8_t codingRate = 1; //!< Code rate (obtained as 4/(codingRate+4)) - double bandwidthHz = 125000; //!< Bandwidth in Hz - uint32_t nPreamble = 8; //!< Number of preamble symbols - bool crcEnabled = 1; //!< Whether Cyclic Redundancy Check is enabled - bool lowDataRateOptimizationEnabled = 0; //!< Whether Low Data Rate Optimization is enabled + uint8_t sf = 7; //!< Spreading Factor + bool headerDisabled = 0; //!< Whether to use implicit header mode + uint8_t codingRate = 1; //!< Code rate (obtained as 4/(codingRate+4)) + double bandwidthHz = 125000; //!< Bandwidth in Hz + uint32_t nPreamble = 8; //!< Number of preamble symbols + bool crcEnabled = 1; //!< Whether Cyclic Redundancy Check is enabled + bool lowDataRateOptimizationEnabled = 0; //!< Whether Low Data Rate Optimization is enabled }; /** * Allow logging of LoraTxParameters like with any other data type. */ -std::ostream &operator << (std::ostream &os, const LoraTxParameters ¶ms); +std::ostream& operator<<(std::ostream& os, const LoraTxParameters& params); /** * \ingroup lorawan @@ -70,269 +73,272 @@ std::ostream &operator << (std::ostream &os, const LoraTxParameters ¶ms); */ class LoraPhy : public Object { -public: - // TypeId - static TypeId GetTypeId (void); - - /** - * Constructor and destructor - */ - LoraPhy (); - virtual ~LoraPhy (); - - /** - * Type definition for a callback for when a packet is correctly received. - * - * This callback can be set by an upper layer that wishes to be informed of - * correct reception events. - */ - typedef Callback > RxOkCallback; - - /** - * Type definition for a callback for when a packet reception fails. - * - * This callback can be set by an upper layer that wishes to be informed of - * failed reception events. - */ - typedef Callback > RxFailedCallback; - - /** - * Type definition for a callback to call when a packet has finished sending. - * - * This callback is used by the MAC layer, to determine when to open a receive - * window. - */ - typedef Callback > TxFinishedCallback; - - /** - * Start receiving a packet. - * - * This method is typically called by LoraChannel. - * - * \param packet The packet that is arriving at this PHY layer. - * \param rxPowerDbm The power of the arriving packet (assumed to be constant - * for the whole reception). - * \param sf The Spreading Factor of the arriving packet. - * \param duration The on air time of this packet. - * \param frequencyMHz The frequency this packet is being transmitted on. - */ - virtual void StartReceive (Ptr packet, double rxPowerDbm, - uint8_t sf, Time duration, - double frequencyMHz) = 0; - - /** - * Finish reception of a packet. - * - * This method is scheduled by StartReceive, based on the packet duration. By - * passing a LoraInterferenceHelper Event to this method, the class will be - * able to identify the packet that is being received among all those that - * were registered as interference by StartReceive. - * - * \param packet The received packet. - * \param event The event that is tied to this packet in the - * LoraInterferenceHelper. - */ - virtual void EndReceive (Ptr packet, - Ptr event) = 0; - - /** - * Instruct the PHY to send a packet according to some parameters. - * - * \param packet The packet to send. - * \param txParams The desired transmission parameters. - * \param frequencyMHz The frequency on which to transmit. - * \param txPowerDbm The power in dBm with which to transmit the packet. - */ - virtual void Send (Ptr packet, LoraTxParameters txParams, - double frequencyMHz, double txPowerDbm) = 0; - - /** - * Whether this device is transmitting or not. - * - * \returns true if the device is currently transmitting a packet, false - * otherwise. - */ - virtual bool IsTransmitting (void) = 0; - - /** - * Whether this device is listening on the specified frequency or not. - * - * \param frequency The frequency to query. - * \returns true if the device is listening on that frequency, false - * otherwise. - */ - virtual bool IsOnFrequency (double frequency) = 0; - - /** - * Set the callback to call upon successful reception of a packet. - * - * This method is typically called by an upper MAC layer that wants to be - * notified after the successful reception of a packet. - */ - void SetReceiveOkCallback (RxOkCallback callback); - - /** - * Set the callback to call upon failed reception of a packet we were - * previously locked on. - * - * This method is typically called by an upper MAC layer that wants to be - * notified after the failed reception of a packet. - */ - void SetReceiveFailedCallback (RxFailedCallback callback); - - /** - * Set the callback to call after transmission of a packet. - * - * This method is typically called by an upper MAC layer that wants to be - * notified after the transmission of a packet. - */ - void SetTxFinishedCallback (TxFinishedCallback callback); - - /** - * Get the mobility model associated to this PHY. - * - * \return The MobilityModel associated to this PHY. - */ - Ptr GetMobility (); - - /** - * Set the mobility model associated to this PHY. - * - * \param mobility The mobility model to associate to this PHY. - */ - void SetMobility (Ptr mobility); - - /** - * Set the LoraChannel instance PHY transmits on. - * - * Typically, there is only one instance per simulation. - * - * \param channel The LoraChannel instance this PHY will transmit on. - */ - void SetChannel (Ptr channel); - - /** - * Get the channel instance associated to this PHY. - * - * \return The LoraChannel instance this PHY transmits on. - */ - Ptr GetChannel (void) const; - - /** - * Get the NetDevice associated to this PHY. - * - * \return The NetDevice associated to this PHY. - */ - Ptr GetDevice (void) const; - - /** - * Set the NetDevice that owns this PHY. - * - * \param device The NetDevice this PHY will reference as its owner. - */ - void SetDevice (Ptr device); - - /** - * Compute the symbol time from SF and BW. - * - * \param txParams The parameters for transmission - * \return TSym, the time required to send a LoRa modulation symbol. - */ - static Time GetTSym (LoraTxParameters txParams); - - /** - * Compute the time that a packet with certain characteristics will take to be - * transmitted. - * - * Besides from the ones saved in LoraTxParameters, the packet's payload - * (obtained through a GetSize () call to accout for the presence of Headers - * and Trailers, too) also influences the packet transmit time. - * - * \param packet The packet that needs to be transmitted. - * \param txParams The set of parameters that will be used for transmission. - * \return The time necessary to transmit the packet. - */ - static Time GetOnAirTime (Ptr packet, LoraTxParameters txParams); - -private: - Ptr m_mobility; //!< The mobility model associated to this PHY. - -protected: - // Member objects - - Ptr m_device; //!< The net device this PHY is attached to. - - Ptr m_channel; //!< The channel this PHY transmits on. - - LoraInterferenceHelper m_interference; //!< The LoraInterferenceHelper - //!associated to this PHY. - - // Trace sources - - /** - * The trace source fired when a packet is sent. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_startSending; - - /** - * The trace source fired when a packet begins the reception process from the - * medium. - * - * \see class CallBackTraceSource - */ - TracedCallback > m_phyRxBeginTrace; - - /** - * The trace source fired when a packet reception ends. - * - * \see class CallBackTraceSource - */ - TracedCallback > m_phyRxEndTrace; - - /** - * The trace source fired when a packet was correctly received. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_successfullyReceivedPacket; - - /** - * The trace source fired when a packet cannot be received because its power - * is below the sensitivity threshold. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_underSensitivity; - - /** - * The trace source fired when a packet cannot be correctly received because - * of interference. - * - * \see class CallBackTraceSource - */ - TracedCallback, uint32_t> m_interferedPacket; - - // Callbacks - - /** - * The callback to perform upon correct reception of a packet. - */ - RxOkCallback m_rxOkCallback; - - /** - * The callback to perform upon failed reception of a packet we were locked on. - */ - RxFailedCallback m_rxFailedCallback; - - /** - * The callback to perform upon the end of a transmission. - */ - TxFinishedCallback m_txFinishedCallback; + public: + // TypeId + static TypeId GetTypeId(void); + + /** + * Constructor and destructor + */ + LoraPhy(); + virtual ~LoraPhy(); + + /** + * Type definition for a callback for when a packet is correctly received. + * + * This callback can be set by an upper layer that wishes to be informed of + * correct reception events. + */ + typedef Callback> RxOkCallback; + + /** + * Type definition for a callback for when a packet reception fails. + * + * This callback can be set by an upper layer that wishes to be informed of + * failed reception events. + */ + typedef Callback> RxFailedCallback; + + /** + * Type definition for a callback to call when a packet has finished sending. + * + * This callback is used by the MAC layer, to determine when to open a receive + * window. + */ + typedef Callback> TxFinishedCallback; + + /** + * Start receiving a packet. + * + * This method is typically called by LoraChannel. + * + * \param packet The packet that is arriving at this PHY layer. + * \param rxPowerDbm The power of the arriving packet (assumed to be constant + * for the whole reception). + * \param sf The Spreading Factor of the arriving packet. + * \param duration The on air time of this packet. + * \param frequencyMHz The frequency this packet is being transmitted on. + */ + virtual void StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz) = 0; + + /** + * Finish reception of a packet. + * + * This method is scheduled by StartReceive, based on the packet duration. By + * passing a LoraInterferenceHelper Event to this method, the class will be + * able to identify the packet that is being received among all those that + * were registered as interference by StartReceive. + * + * \param packet The received packet. + * \param event The event that is tied to this packet in the + * LoraInterferenceHelper. + */ + virtual void EndReceive(Ptr packet, Ptr event) = 0; + + /** + * Instruct the PHY to send a packet according to some parameters. + * + * \param packet The packet to send. + * \param txParams The desired transmission parameters. + * \param frequencyMHz The frequency on which to transmit. + * \param txPowerDbm The power in dBm with which to transmit the packet. + */ + virtual void Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm) = 0; + + /** + * Whether this device is transmitting or not. + * + * \returns true if the device is currently transmitting a packet, false + * otherwise. + */ + virtual bool IsTransmitting(void) = 0; + + /** + * Whether this device is listening on the specified frequency or not. + * + * \param frequency The frequency to query. + * \returns true if the device is listening on that frequency, false + * otherwise. + */ + virtual bool IsOnFrequency(double frequency) = 0; + + /** + * Set the callback to call upon successful reception of a packet. + * + * This method is typically called by an upper MAC layer that wants to be + * notified after the successful reception of a packet. + */ + void SetReceiveOkCallback(RxOkCallback callback); + + /** + * Set the callback to call upon failed reception of a packet we were + * previously locked on. + * + * This method is typically called by an upper MAC layer that wants to be + * notified after the failed reception of a packet. + */ + void SetReceiveFailedCallback(RxFailedCallback callback); + + /** + * Set the callback to call after transmission of a packet. + * + * This method is typically called by an upper MAC layer that wants to be + * notified after the transmission of a packet. + */ + void SetTxFinishedCallback(TxFinishedCallback callback); + + /** + * Get the mobility model associated to this PHY. + * + * \return The MobilityModel associated to this PHY. + */ + Ptr GetMobility(); + + /** + * Set the mobility model associated to this PHY. + * + * \param mobility The mobility model to associate to this PHY. + */ + void SetMobility(Ptr mobility); + + /** + * Set the LoraChannel instance PHY transmits on. + * + * Typically, there is only one instance per simulation. + * + * \param channel The LoraChannel instance this PHY will transmit on. + */ + void SetChannel(Ptr channel); + + /** + * Get the channel instance associated to this PHY. + * + * \return The LoraChannel instance this PHY transmits on. + */ + Ptr GetChannel(void) const; + + /** + * Get the NetDevice associated to this PHY. + * + * \return The NetDevice associated to this PHY. + */ + Ptr GetDevice(void) const; + + /** + * Set the NetDevice that owns this PHY. + * + * \param device The NetDevice this PHY will reference as its owner. + */ + void SetDevice(Ptr device); + + /** + * Compute the symbol time from SF and BW. + * + * \param txParams The parameters for transmission + * \return TSym, the time required to send a LoRa modulation symbol. + */ + static Time GetTSym(LoraTxParameters txParams); + + /** + * Compute the time that a packet with certain characteristics will take to be + * transmitted. + * + * Besides from the ones saved in LoraTxParameters, the packet's payload + * (obtained through a GetSize () call to accout for the presence of Headers + * and Trailers, too) also influences the packet transmit time. + * + * \param packet The packet that needs to be transmitted. + * \param txParams The set of parameters that will be used for transmission. + * \return The time necessary to transmit the packet. + */ + static Time GetOnAirTime(Ptr packet, LoraTxParameters txParams); + + private: + Ptr m_mobility; //!< The mobility model associated to this PHY. + + protected: + // Member objects + + Ptr m_device; //!< The net device this PHY is attached to. + + Ptr m_channel; //!< The channel this PHY transmits on. + + LoraInterferenceHelper m_interference; //!< The LoraInterferenceHelper + //! associated to this PHY. + + // Trace sources + + /** + * The trace source fired when a packet is sent. + * + * \see class CallBackTraceSource + */ + TracedCallback, uint32_t> m_startSending; + + /** + * The trace source fired when a packet begins the reception process from the + * medium. + * + * \see class CallBackTraceSource + */ + TracedCallback> m_phyRxBeginTrace; + + /** + * The trace source fired when a packet reception ends. + * + * \see class CallBackTraceSource + */ + TracedCallback> m_phyRxEndTrace; + + /** + * The trace source fired when a packet was correctly received. + * + * \see class CallBackTraceSource + */ + TracedCallback, uint32_t> m_successfullyReceivedPacket; + + /** + * The trace source fired when a packet cannot be received because its power + * is below the sensitivity threshold. + * + * \see class CallBackTraceSource + */ + TracedCallback, uint32_t> m_underSensitivity; + + /** + * The trace source fired when a packet cannot be correctly received because + * of interference. + * + * \see class CallBackTraceSource + */ + TracedCallback, uint32_t> m_interferedPacket; + + // Callbacks + + /** + * The callback to perform upon correct reception of a packet. + */ + RxOkCallback m_rxOkCallback; + + /** + * The callback to perform upon failed reception of a packet we were locked on. + */ + RxFailedCallback m_rxFailedCallback; + + /** + * The callback to perform upon the end of a transmission. + */ + TxFinishedCallback m_txFinishedCallback; }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_PHY_H */ diff --git a/model/lora-radio-energy-model.cc b/model/lora-radio-energy-model.cc index 5e6b922d21..4668016e21 100644 --- a/model/lora-radio-energy-model.cc +++ b/model/lora-radio-energy-model.cc @@ -14,300 +14,303 @@ * Author: Romagnolo Stefano */ -#include "ns3/log.h" -#include "ns3/simulator.h" -#include "ns3/pointer.h" -#include "ns3/energy-source.h" #include "lora-radio-energy-model.h" +#include "ns3/energy-source.h" +#include "ns3/log.h" +#include "ns3/pointer.h" +#include "ns3/simulator.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraRadioEnergyModel"); +NS_LOG_COMPONENT_DEFINE("LoraRadioEnergyModel"); -NS_OBJECT_ENSURE_REGISTERED (LoraRadioEnergyModel); +NS_OBJECT_ENSURE_REGISTERED(LoraRadioEnergyModel); TypeId -LoraRadioEnergyModel::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::LoraRadioEnergyModel") - .SetParent () - .SetGroupName ("Energy") - .AddConstructor () - .AddAttribute ("StandbyCurrentA", - "The default radio Standby current in Ampere.", - DoubleValue (0.0014), // idle mode = 1.4mA - MakeDoubleAccessor (&LoraRadioEnergyModel::SetStandbyCurrentA, - &LoraRadioEnergyModel::GetStandbyCurrentA), - MakeDoubleChecker ()) - .AddAttribute ("TxCurrentA", - "The radio Tx current in Ampere.", - DoubleValue (0.028), // transmit at 0dBm = 28mA - MakeDoubleAccessor (&LoraRadioEnergyModel::SetTxCurrentA, - &LoraRadioEnergyModel::GetTxCurrentA), - MakeDoubleChecker ()) - .AddAttribute ("RxCurrentA", - "The radio Rx current in Ampere.", - DoubleValue (0.0112), // receive mode = 11.2mA - MakeDoubleAccessor (&LoraRadioEnergyModel::SetRxCurrentA, - &LoraRadioEnergyModel::GetRxCurrentA), - MakeDoubleChecker ()) - .AddAttribute ("SleepCurrentA", - "The radio Sleep current in Ampere.", - DoubleValue (0.0000015), // sleep mode = 1.5microA - MakeDoubleAccessor (&LoraRadioEnergyModel::SetSleepCurrentA, - &LoraRadioEnergyModel::GetSleepCurrentA), - MakeDoubleChecker ()) - .AddAttribute ("TxCurrentModel", "A pointer to the attached tx current model.", - PointerValue (), - MakePointerAccessor (&LoraRadioEnergyModel::m_txCurrentModel), - MakePointerChecker ()) - .AddTraceSource ("TotalEnergyConsumption", - "Total energy consumption of the radio device.", - MakeTraceSourceAccessor (&LoraRadioEnergyModel::m_totalEnergyConsumption), - "ns3::TracedValueCallback::Double") - ; - return tid; -} - -LoraRadioEnergyModel::LoraRadioEnergyModel () -{ - NS_LOG_FUNCTION (this); - m_currentState = EndDeviceLoraPhy::SLEEP; // initially STANDBY - m_lastUpdateTime = Seconds (0.0); - m_nPendingChangeState = 0; - m_isSupersededChangeState = false; - m_energyDepletionCallback.Nullify (); - m_source = NULL; - // set callback for EndDeviceLoraPhy listener - m_listener = new LoraRadioEnergyModelPhyListener; - m_listener->SetChangeStateCallback (MakeCallback (&DeviceEnergyModel::ChangeState, this)); - // set callback for updating the tx current - m_listener->SetUpdateTxCurrentCallback (MakeCallback (&LoraRadioEnergyModel::SetTxCurrentFromModel, this)); -} - -LoraRadioEnergyModel::~LoraRadioEnergyModel () -{ - NS_LOG_FUNCTION (this); - delete m_listener; +LoraRadioEnergyModel::GetTypeId(void) +{ + static TypeId tid = + TypeId("ns3::LoraRadioEnergyModel") + .SetParent() + .SetGroupName("Energy") + .AddConstructor() + .AddAttribute("StandbyCurrentA", + "The default radio Standby current in Ampere.", + DoubleValue(0.0014), // idle mode = 1.4mA + MakeDoubleAccessor(&LoraRadioEnergyModel::SetStandbyCurrentA, + &LoraRadioEnergyModel::GetStandbyCurrentA), + MakeDoubleChecker()) + .AddAttribute("TxCurrentA", + "The radio Tx current in Ampere.", + DoubleValue(0.028), // transmit at 0dBm = 28mA + MakeDoubleAccessor(&LoraRadioEnergyModel::SetTxCurrentA, + &LoraRadioEnergyModel::GetTxCurrentA), + MakeDoubleChecker()) + .AddAttribute("RxCurrentA", + "The radio Rx current in Ampere.", + DoubleValue(0.0112), // receive mode = 11.2mA + MakeDoubleAccessor(&LoraRadioEnergyModel::SetRxCurrentA, + &LoraRadioEnergyModel::GetRxCurrentA), + MakeDoubleChecker()) + .AddAttribute("SleepCurrentA", + "The radio Sleep current in Ampere.", + DoubleValue(0.0000015), // sleep mode = 1.5microA + MakeDoubleAccessor(&LoraRadioEnergyModel::SetSleepCurrentA, + &LoraRadioEnergyModel::GetSleepCurrentA), + MakeDoubleChecker()) + .AddAttribute("TxCurrentModel", + "A pointer to the attached tx current model.", + PointerValue(), + MakePointerAccessor(&LoraRadioEnergyModel::m_txCurrentModel), + MakePointerChecker()) + .AddTraceSource( + "TotalEnergyConsumption", + "Total energy consumption of the radio device.", + MakeTraceSourceAccessor(&LoraRadioEnergyModel::m_totalEnergyConsumption), + "ns3::TracedValueCallback::Double"); + return tid; +} + +LoraRadioEnergyModel::LoraRadioEnergyModel() +{ + NS_LOG_FUNCTION(this); + m_currentState = EndDeviceLoraPhy::SLEEP; // initially STANDBY + m_lastUpdateTime = Seconds(0.0); + m_nPendingChangeState = 0; + m_isSupersededChangeState = false; + m_energyDepletionCallback.Nullify(); + m_source = NULL; + // set callback for EndDeviceLoraPhy listener + m_listener = new LoraRadioEnergyModelPhyListener; + m_listener->SetChangeStateCallback(MakeCallback(&DeviceEnergyModel::ChangeState, this)); + // set callback for updating the tx current + m_listener->SetUpdateTxCurrentCallback( + MakeCallback(&LoraRadioEnergyModel::SetTxCurrentFromModel, this)); +} + +LoraRadioEnergyModel::~LoraRadioEnergyModel() +{ + NS_LOG_FUNCTION(this); + delete m_listener; } void -LoraRadioEnergyModel::SetEnergySource (Ptr source) +LoraRadioEnergyModel::SetEnergySource(Ptr source) { - NS_LOG_FUNCTION (this << source); - NS_ASSERT (source != NULL); - m_source = source; + NS_LOG_FUNCTION(this << source); + NS_ASSERT(source != NULL); + m_source = source; } double -LoraRadioEnergyModel::GetTotalEnergyConsumption (void) const +LoraRadioEnergyModel::GetTotalEnergyConsumption(void) const { - NS_LOG_FUNCTION (this); - return m_totalEnergyConsumption; + NS_LOG_FUNCTION(this); + return m_totalEnergyConsumption; } double -LoraRadioEnergyModel::GetStandbyCurrentA (void) const +LoraRadioEnergyModel::GetStandbyCurrentA(void) const { - NS_LOG_FUNCTION (this); - return m_idleCurrentA; + NS_LOG_FUNCTION(this); + return m_idleCurrentA; } void -LoraRadioEnergyModel::SetStandbyCurrentA (double idleCurrentA) +LoraRadioEnergyModel::SetStandbyCurrentA(double idleCurrentA) { - NS_LOG_FUNCTION (this << idleCurrentA); - m_idleCurrentA = idleCurrentA; + NS_LOG_FUNCTION(this << idleCurrentA); + m_idleCurrentA = idleCurrentA; } double -LoraRadioEnergyModel::GetTxCurrentA (void) const +LoraRadioEnergyModel::GetTxCurrentA(void) const { - NS_LOG_FUNCTION (this); - return m_txCurrentA; + NS_LOG_FUNCTION(this); + return m_txCurrentA; } void -LoraRadioEnergyModel::SetTxCurrentA (double txCurrentA) +LoraRadioEnergyModel::SetTxCurrentA(double txCurrentA) { - NS_LOG_FUNCTION (this << txCurrentA); - m_txCurrentA = txCurrentA; + NS_LOG_FUNCTION(this << txCurrentA); + m_txCurrentA = txCurrentA; } double -LoraRadioEnergyModel::GetRxCurrentA (void) const +LoraRadioEnergyModel::GetRxCurrentA(void) const { - NS_LOG_FUNCTION (this); - return m_rxCurrentA; + NS_LOG_FUNCTION(this); + return m_rxCurrentA; } void -LoraRadioEnergyModel::SetRxCurrentA (double rxCurrentA) +LoraRadioEnergyModel::SetRxCurrentA(double rxCurrentA) { - NS_LOG_FUNCTION (this << rxCurrentA); - m_rxCurrentA = rxCurrentA; + NS_LOG_FUNCTION(this << rxCurrentA); + m_rxCurrentA = rxCurrentA; } double -LoraRadioEnergyModel::GetSleepCurrentA (void) const +LoraRadioEnergyModel::GetSleepCurrentA(void) const { - NS_LOG_FUNCTION (this); - return m_sleepCurrentA; + NS_LOG_FUNCTION(this); + return m_sleepCurrentA; } void -LoraRadioEnergyModel::SetSleepCurrentA (double sleepCurrentA) +LoraRadioEnergyModel::SetSleepCurrentA(double sleepCurrentA) { - NS_LOG_FUNCTION (this << sleepCurrentA); - m_sleepCurrentA = sleepCurrentA; + NS_LOG_FUNCTION(this << sleepCurrentA); + m_sleepCurrentA = sleepCurrentA; } EndDeviceLoraPhy::State -LoraRadioEnergyModel::GetCurrentState (void) const +LoraRadioEnergyModel::GetCurrentState(void) const { - NS_LOG_FUNCTION (this); - return m_currentState; + NS_LOG_FUNCTION(this); + return m_currentState; } void -LoraRadioEnergyModel::SetEnergyDepletionCallback ( - LoraRadioEnergyDepletionCallback callback) +LoraRadioEnergyModel::SetEnergyDepletionCallback(LoraRadioEnergyDepletionCallback callback) { - NS_LOG_FUNCTION (this); - if (callback.IsNull ()) + NS_LOG_FUNCTION(this); + if (callback.IsNull()) { - NS_LOG_DEBUG ("LoraRadioEnergyModel:Setting NULL energy depletion callback!"); + NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy depletion callback!"); } - m_energyDepletionCallback = callback; + m_energyDepletionCallback = callback; } void -LoraRadioEnergyModel::SetEnergyRechargedCallback ( - LoraRadioEnergyRechargedCallback callback) +LoraRadioEnergyModel::SetEnergyRechargedCallback(LoraRadioEnergyRechargedCallback callback) { - NS_LOG_FUNCTION (this); - if (callback.IsNull ()) + NS_LOG_FUNCTION(this); + if (callback.IsNull()) { - NS_LOG_DEBUG ("LoraRadioEnergyModel:Setting NULL energy recharged callback!"); + NS_LOG_DEBUG("LoraRadioEnergyModel:Setting NULL energy recharged callback!"); } - m_energyRechargedCallback = callback; + m_energyRechargedCallback = callback; } void -LoraRadioEnergyModel::SetTxCurrentModel (Ptr model) +LoraRadioEnergyModel::SetTxCurrentModel(Ptr model) { - m_txCurrentModel = model; + m_txCurrentModel = model; } void -LoraRadioEnergyModel::SetTxCurrentFromModel (double txPowerDbm) +LoraRadioEnergyModel::SetTxCurrentFromModel(double txPowerDbm) { - if (m_txCurrentModel) + if (m_txCurrentModel) { - m_txCurrentA = m_txCurrentModel->CalcTxCurrent (txPowerDbm); + m_txCurrentA = m_txCurrentModel->CalcTxCurrent(txPowerDbm); } } void -LoraRadioEnergyModel::ChangeState (int newState) +LoraRadioEnergyModel::ChangeState(int newState) { - NS_LOG_FUNCTION (this << newState); + NS_LOG_FUNCTION(this << newState); - Time duration = Simulator::Now () - m_lastUpdateTime; - NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid + Time duration = Simulator::Now() - m_lastUpdateTime; + NS_ASSERT(duration.GetNanoSeconds() >= 0); // check if duration is valid - // energy to decrease = current * voltage * time - double energyToDecrease = 0.0; - double supplyVoltage = m_source->GetSupplyVoltage (); - switch (m_currentState) + // energy to decrease = current * voltage * time + double energyToDecrease = 0.0; + double supplyVoltage = m_source->GetSupplyVoltage(); + switch (m_currentState) { case EndDeviceLoraPhy::STANDBY: - energyToDecrease = duration.GetSeconds () * m_idleCurrentA * supplyVoltage; - break; + energyToDecrease = duration.GetSeconds() * m_idleCurrentA * supplyVoltage; + break; case EndDeviceLoraPhy::TX: - energyToDecrease = duration.GetSeconds () * m_txCurrentA * supplyVoltage; - break; + energyToDecrease = duration.GetSeconds() * m_txCurrentA * supplyVoltage; + break; case EndDeviceLoraPhy::RX: - energyToDecrease = duration.GetSeconds () * m_rxCurrentA * supplyVoltage; - break; + energyToDecrease = duration.GetSeconds() * m_rxCurrentA * supplyVoltage; + break; case EndDeviceLoraPhy::SLEEP: - energyToDecrease = duration.GetSeconds () * m_sleepCurrentA * supplyVoltage; - break; + energyToDecrease = duration.GetSeconds() * m_sleepCurrentA * supplyVoltage; + break; default: - NS_FATAL_ERROR ("LoraRadioEnergyModel:Undefined radio state: " << m_currentState); + NS_FATAL_ERROR("LoraRadioEnergyModel:Undefined radio state: " << m_currentState); } - // update total energy consumption - m_totalEnergyConsumption += energyToDecrease; + // update total energy consumption + m_totalEnergyConsumption += energyToDecrease; - // update last update time stamp - m_lastUpdateTime = Simulator::Now (); + // update last update time stamp + m_lastUpdateTime = Simulator::Now(); - m_nPendingChangeState++; + m_nPendingChangeState++; - // notify energy source - m_source->UpdateEnergySource (); + // notify energy source + m_source->UpdateEnergySource(); - // in case the energy source is found to be depleted during the last update, a callback might be - // invoked that might cause a change in the Lora PHY state (e.g., the PHY is put into SLEEP mode). - // This in turn causes a new call to this member function, with the consequence that the previous - // instance is resumed after the termination of the new instance. In particular, the state set - // by the previous instance is erroneously the final state stored in m_currentState. The check below - // ensures that previous instances do not change m_currentState. + // in case the energy source is found to be depleted during the last update, a callback might be + // invoked that might cause a change in the Lora PHY state (e.g., the PHY is put into SLEEP + // mode). This in turn causes a new call to this member function, with the consequence that the + // previous instance is resumed after the termination of the new instance. In particular, the + // state set by the previous instance is erroneously the final state stored in m_currentState. + // The check below ensures that previous instances do not change m_currentState. - if (!m_isSupersededChangeState) + if (!m_isSupersededChangeState) { - // update current state & last update time stamp - SetLoraRadioState ((EndDeviceLoraPhy::State) newState); + // update current state & last update time stamp + SetLoraRadioState((EndDeviceLoraPhy::State)newState); - // some debug message - NS_LOG_DEBUG ("LoraRadioEnergyModel:Total energy consumption is " << - m_totalEnergyConsumption << "J"); + // some debug message + NS_LOG_DEBUG("LoraRadioEnergyModel:Total energy consumption is " << m_totalEnergyConsumption + << "J"); } - m_isSupersededChangeState = (m_nPendingChangeState > 1); + m_isSupersededChangeState = (m_nPendingChangeState > 1); - m_nPendingChangeState--; + m_nPendingChangeState--; } void -LoraRadioEnergyModel::HandleEnergyDepletion (void) +LoraRadioEnergyModel::HandleEnergyDepletion(void) { - NS_LOG_FUNCTION (this); - NS_LOG_DEBUG ("LoraRadioEnergyModel:Energy is depleted!"); - // invoke energy depletion callback, if set. - if (!m_energyDepletionCallback.IsNull ()) + NS_LOG_FUNCTION(this); + NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is depleted!"); + // invoke energy depletion callback, if set. + if (!m_energyDepletionCallback.IsNull()) { - m_energyDepletionCallback (); + m_energyDepletionCallback(); } } void -LoraRadioEnergyModel::HandleEnergyChanged (void) +LoraRadioEnergyModel::HandleEnergyChanged(void) { - NS_LOG_FUNCTION (this); - NS_LOG_DEBUG ("LoraRadioEnergyModel:Energy changed!"); + NS_LOG_FUNCTION(this); + NS_LOG_DEBUG("LoraRadioEnergyModel:Energy changed!"); } void -LoraRadioEnergyModel::HandleEnergyRecharged (void) +LoraRadioEnergyModel::HandleEnergyRecharged(void) { - NS_LOG_FUNCTION (this); - NS_LOG_DEBUG ("LoraRadioEnergyModel:Energy is recharged!"); - // invoke energy recharged callback, if set. - if (!m_energyRechargedCallback.IsNull ()) + NS_LOG_FUNCTION(this); + NS_LOG_DEBUG("LoraRadioEnergyModel:Energy is recharged!"); + // invoke energy recharged callback, if set. + if (!m_energyRechargedCallback.IsNull()) { - m_energyRechargedCallback (); + m_energyRechargedCallback(); } } -LoraRadioEnergyModelPhyListener * -LoraRadioEnergyModel::GetPhyListener (void) +LoraRadioEnergyModelPhyListener* +LoraRadioEnergyModel::GetPhyListener(void) { - NS_LOG_FUNCTION (this); - return m_listener; + NS_LOG_FUNCTION(this); + return m_listener; } /* @@ -315,134 +318,135 @@ LoraRadioEnergyModel::GetPhyListener (void) */ void -LoraRadioEnergyModel::DoDispose (void) +LoraRadioEnergyModel::DoDispose(void) { - NS_LOG_FUNCTION (this); - m_source = NULL; - m_energyDepletionCallback.Nullify (); + NS_LOG_FUNCTION(this); + m_source = NULL; + m_energyDepletionCallback.Nullify(); } double -LoraRadioEnergyModel::DoGetCurrentA (void) const +LoraRadioEnergyModel::DoGetCurrentA(void) const { - NS_LOG_FUNCTION (this); - switch (m_currentState) + NS_LOG_FUNCTION(this); + switch (m_currentState) { case EndDeviceLoraPhy::STANDBY: - return m_idleCurrentA; + return m_idleCurrentA; case EndDeviceLoraPhy::TX: - return m_txCurrentA; + return m_txCurrentA; case EndDeviceLoraPhy::RX: - return m_rxCurrentA; + return m_rxCurrentA; case EndDeviceLoraPhy::SLEEP: - return m_sleepCurrentA; + return m_sleepCurrentA; default: - NS_FATAL_ERROR ("LoraRadioEnergyModel:Undefined radio state:" << m_currentState); + NS_FATAL_ERROR("LoraRadioEnergyModel:Undefined radio state:" << m_currentState); } } void -LoraRadioEnergyModel::SetLoraRadioState (const EndDeviceLoraPhy::State state) +LoraRadioEnergyModel::SetLoraRadioState(const EndDeviceLoraPhy::State state) { - NS_LOG_FUNCTION (this << state); - m_currentState = state; - std::string stateName; - switch (state) + NS_LOG_FUNCTION(this << state); + m_currentState = state; + std::string stateName; + switch (state) { case EndDeviceLoraPhy::STANDBY: - stateName = "STANDBY"; - break; + stateName = "STANDBY"; + break; case EndDeviceLoraPhy::TX: - stateName = "TX"; - break; + stateName = "TX"; + break; case EndDeviceLoraPhy::RX: - stateName = "RX"; - break; + stateName = "RX"; + break; case EndDeviceLoraPhy::SLEEP: - stateName = "SLEEP"; - break; + stateName = "SLEEP"; + break; } - NS_LOG_DEBUG ("LoraRadioEnergyModel:Switching to state: " << stateName << - " at time = " << Simulator::Now ().GetSeconds () << " s"); + NS_LOG_DEBUG("LoraRadioEnergyModel:Switching to state: " + << stateName << " at time = " << Simulator::Now().GetSeconds() << " s"); } // -------------------------------------------------------------------------- // -LoraRadioEnergyModelPhyListener::LoraRadioEnergyModelPhyListener () +LoraRadioEnergyModelPhyListener::LoraRadioEnergyModelPhyListener() { - NS_LOG_FUNCTION (this); - m_changeStateCallback.Nullify (); - m_updateTxCurrentCallback.Nullify (); + NS_LOG_FUNCTION(this); + m_changeStateCallback.Nullify(); + m_updateTxCurrentCallback.Nullify(); } -LoraRadioEnergyModelPhyListener::~LoraRadioEnergyModelPhyListener () +LoraRadioEnergyModelPhyListener::~LoraRadioEnergyModelPhyListener() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -LoraRadioEnergyModelPhyListener::SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback) +LoraRadioEnergyModelPhyListener::SetChangeStateCallback( + DeviceEnergyModel::ChangeStateCallback callback) { - NS_LOG_FUNCTION (this << &callback); - NS_ASSERT (!callback.IsNull ()); - m_changeStateCallback = callback; + NS_LOG_FUNCTION(this << &callback); + NS_ASSERT(!callback.IsNull()); + m_changeStateCallback = callback; } void -LoraRadioEnergyModelPhyListener::SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback) +LoraRadioEnergyModelPhyListener::SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback) { - NS_LOG_FUNCTION (this << &callback); - NS_ASSERT (!callback.IsNull ()); - m_updateTxCurrentCallback = callback; + NS_LOG_FUNCTION(this << &callback); + NS_ASSERT(!callback.IsNull()); + m_updateTxCurrentCallback = callback; } void -LoraRadioEnergyModelPhyListener::NotifyRxStart () +LoraRadioEnergyModelPhyListener::NotifyRxStart() { - NS_LOG_FUNCTION (this); - if (m_changeStateCallback.IsNull ()) + NS_LOG_FUNCTION(this); + if (m_changeStateCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Change state callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!"); } - m_changeStateCallback (EndDeviceLoraPhy::RX); + m_changeStateCallback(EndDeviceLoraPhy::RX); } void -LoraRadioEnergyModelPhyListener::NotifyTxStart (double txPowerDbm) +LoraRadioEnergyModelPhyListener::NotifyTxStart(double txPowerDbm) { - NS_LOG_FUNCTION (this << txPowerDbm); - if (m_updateTxCurrentCallback.IsNull ()) + NS_LOG_FUNCTION(this << txPowerDbm); + if (m_updateTxCurrentCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Update tx current callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Update tx current callback not set!"); } - m_updateTxCurrentCallback (txPowerDbm); - if (m_changeStateCallback.IsNull ()) + m_updateTxCurrentCallback(txPowerDbm); + if (m_changeStateCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Change state callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!"); } - m_changeStateCallback (EndDeviceLoraPhy::TX); + m_changeStateCallback(EndDeviceLoraPhy::TX); } void -LoraRadioEnergyModelPhyListener::NotifySleep (void) +LoraRadioEnergyModelPhyListener::NotifySleep(void) { - NS_LOG_FUNCTION (this); - if (m_changeStateCallback.IsNull ()) + NS_LOG_FUNCTION(this); + if (m_changeStateCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Change state callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!"); } - m_changeStateCallback (EndDeviceLoraPhy::SLEEP); + m_changeStateCallback(EndDeviceLoraPhy::SLEEP); } void -LoraRadioEnergyModelPhyListener::NotifyStandby (void) +LoraRadioEnergyModelPhyListener::NotifyStandby(void) { - NS_LOG_FUNCTION (this); - if (m_changeStateCallback.IsNull ()) + NS_LOG_FUNCTION(this); + if (m_changeStateCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Change state callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!"); } - m_changeStateCallback (EndDeviceLoraPhy::STANDBY); + m_changeStateCallback(EndDeviceLoraPhy::STANDBY); } /* @@ -450,15 +454,15 @@ LoraRadioEnergyModelPhyListener::NotifyStandby (void) */ void -LoraRadioEnergyModelPhyListener::SwitchToStandby (void) +LoraRadioEnergyModelPhyListener::SwitchToStandby(void) { - NS_LOG_FUNCTION (this); - if (m_changeStateCallback.IsNull ()) + NS_LOG_FUNCTION(this); + if (m_changeStateCallback.IsNull()) { - NS_FATAL_ERROR ("LoraRadioEnergyModelPhyListener:Change state callback not set!"); + NS_FATAL_ERROR("LoraRadioEnergyModelPhyListener:Change state callback not set!"); } - m_changeStateCallback (EndDeviceLoraPhy::STANDBY); + m_changeStateCallback(EndDeviceLoraPhy::STANDBY); } -} +} // namespace lorawan } // namespace ns3 diff --git a/model/lora-radio-energy-model.h b/model/lora-radio-energy-model.h index 91f9f5cf1c..55df71208e 100644 --- a/model/lora-radio-energy-model.h +++ b/model/lora-radio-energy-model.h @@ -17,93 +17,94 @@ #ifndef LORA_RADIO_ENERGY_MODEL_H #define LORA_RADIO_ENERGY_MODEL_H -#include "ns3/device-energy-model.h" -#include "ns3/traced-value.h" #include "end-device-lora-phy.h" #include "lora-tx-current-model.h" -namespace ns3 { -namespace lorawan { +#include "ns3/device-energy-model.h" +#include "ns3/traced-value.h" + +namespace ns3 +{ +namespace lorawan +{ /** * \ingroup energy */ class LoraRadioEnergyModelPhyListener : public EndDeviceLoraPhyListener { -public: - /** - * Callback type for updating the transmit current based on the nominal tx power. - */ - typedef Callback UpdateTxCurrentCallback; - - LoraRadioEnergyModelPhyListener (); - virtual ~LoraRadioEnergyModelPhyListener (); - - /** - * \brief Sets the change state callback. Used by helper class. - * - * \param callback Change state callback. - */ - void SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback); - - /** - * \brief Sets the update tx current callback. - * - * \param callback Update tx current callback. - */ - void SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback); - - /** - * \brief Switches the LoraRadioEnergyModel to RX state. - * - * \param duration the expected duration of the packet reception. - * - * Defined in ns3::LoraEndDevicePhyListener - */ - void NotifyRxStart (void); - - /** - * \brief Switches the LoraRadioEnergyModel to TX state and switches back to - * STANDBY after TX duration. - * - * \param duration the expected transmission duration. - * \param txPowerDbm the nominal tx power in dBm - * - * Defined in ns3::LoraEndDevicePhyListener - */ - void NotifyTxStart (double txPowerDbm); - - /** - * Defined in ns3::LoraEndDevicePhyListener - */ - void NotifySleep (void); - - /** - * Defined in ns3::LoraEndDevicePhyListener - */ - void NotifyStandby (void); - - -private: - /** - * A helper function that makes scheduling m_changeStateCallback possible. - */ - void SwitchToStandby (void); - - /** - * Change state callback used to notify the LoraRadioEnergyModel of a state - * change. - */ - DeviceEnergyModel::ChangeStateCallback m_changeStateCallback; - - /** - * Callback used to update the tx current stored in LoraRadioEnergyModel based on - * the nominal tx power used to transmit the current frame. - */ - UpdateTxCurrentCallback m_updateTxCurrentCallback; + public: + /** + * Callback type for updating the transmit current based on the nominal tx power. + */ + typedef Callback UpdateTxCurrentCallback; + + LoraRadioEnergyModelPhyListener(); + virtual ~LoraRadioEnergyModelPhyListener(); + + /** + * \brief Sets the change state callback. Used by helper class. + * + * \param callback Change state callback. + */ + void SetChangeStateCallback(DeviceEnergyModel::ChangeStateCallback callback); + + /** + * \brief Sets the update tx current callback. + * + * \param callback Update tx current callback. + */ + void SetUpdateTxCurrentCallback(UpdateTxCurrentCallback callback); + + /** + * \brief Switches the LoraRadioEnergyModel to RX state. + * + * \param duration the expected duration of the packet reception. + * + * Defined in ns3::LoraEndDevicePhyListener + */ + void NotifyRxStart(void); + + /** + * \brief Switches the LoraRadioEnergyModel to TX state and switches back to + * STANDBY after TX duration. + * + * \param duration the expected transmission duration. + * \param txPowerDbm the nominal tx power in dBm + * + * Defined in ns3::LoraEndDevicePhyListener + */ + void NotifyTxStart(double txPowerDbm); + + /** + * Defined in ns3::LoraEndDevicePhyListener + */ + void NotifySleep(void); + + /** + * Defined in ns3::LoraEndDevicePhyListener + */ + void NotifyStandby(void); + + private: + /** + * A helper function that makes scheduling m_changeStateCallback possible. + */ + void SwitchToStandby(void); + + /** + * Change state callback used to notify the LoraRadioEnergyModel of a state + * change. + */ + DeviceEnergyModel::ChangeStateCallback m_changeStateCallback; + + /** + * Callback used to update the tx current stored in LoraRadioEnergyModel based on + * the nominal tx power used to transmit the current frame. + */ + UpdateTxCurrentCallback m_updateTxCurrentCallback; }; - /** * \ingroup energy * \brief A WiFi radio energy model. @@ -126,210 +127,209 @@ class LoraRadioEnergyModelPhyListener : public EndDeviceLoraPhyListener */ class LoraRadioEnergyModel : public DeviceEnergyModel { -public: - /** - * Callback type for energy depletion handling. - */ - typedef Callback LoraRadioEnergyDepletionCallback; - - /** - * Callback type for energy recharged handling. - */ - typedef Callback LoraRadioEnergyRechargedCallback; - - /** - * \brief Get the type ID. - * \return the object TypeId - */ - static TypeId GetTypeId (void); - LoraRadioEnergyModel (); - virtual ~LoraRadioEnergyModel (); - - /** - * \brief Sets pointer to EnergySouce installed on node. - * - * \param source Pointer to EnergySource installed on node. - * - * Implements DeviceEnergyModel::SetEnergySource. - */ - void SetEnergySource (Ptr source); - - /** - * \returns Total energy consumption of the wifi device. - * - * Implements DeviceEnergyModel::GetTotalEnergyConsumption. - */ - double GetTotalEnergyConsumption (void) const; - - // Setter & getters for state power consumption. - /** - * \brief Gets idle current. - * - * \returns idle current of the lora device. - */ - double GetStandbyCurrentA (void) const; - /** - * \brief Sets idle current. - * - * \param idleCurrentA the idle current - */ - void SetStandbyCurrentA (double idleCurrentA); - /** - * \brief Gets transmit current. - * - * \returns transmit current of the lora device. - */ - double GetTxCurrentA (void) const; - /** - * \brief Sets transmit current. - * - * \param txCurrentA the transmit current - */ - void SetTxCurrentA (double txCurrentA); - /** - * \brief Gets receive current. - * - * \returns receive current of the lora device. - */ - double GetRxCurrentA (void) const; - /** - * \brief Sets receive current. - * - * \param rxCurrentA the receive current - */ - void SetRxCurrentA (double rxCurrentA); - /** - * \brief Gets sleep current. - * - * \returns sleep current of the lora device. - */ - double GetSleepCurrentA (void) const; - /** - * \brief Sets sleep current. - * - * \param sleepCurrentA the sleep current - */ - void SetSleepCurrentA (double sleepCurrentA); - - /** - * \returns Current state. - */ - EndDeviceLoraPhy::State GetCurrentState (void) const; - - /** - * \param callback Callback function. - * - * Sets callback for energy depletion handling. - */ - void SetEnergyDepletionCallback (LoraRadioEnergyDepletionCallback callback); - - /** - * \param callback Callback function. - * - * Sets callback for energy recharged handling. - */ - void SetEnergyRechargedCallback (LoraRadioEnergyRechargedCallback callback); - - /** - * \param model the model used to compute the lora tx current. - */ - // NOTICE VERY WELL: Current Model linear or constant as possible choices - void SetTxCurrentModel (Ptr model); - - /** - * \brief Calls the CalcTxCurrent method of the tx current model to - * compute the tx current based on such model - * - * \param txPowerDbm the nominal tx power in dBm - */ - // NOTICE VERY WELL: Current Model linear or constant as possible choices - void SetTxCurrentFromModel (double txPowerDbm); - - /** - * \brief Changes state of the LoraRadioEnergyMode. - * - * \param newState New state the lora radio is in. - * - * Implements DeviceEnergyModel::ChangeState. - */ - void ChangeState (int newState); - - /** - * \brief Handles energy depletion. - * - * Implements DeviceEnergyModel::HandleEnergyDepletion - */ - void HandleEnergyDepletion (void); - - /** - * \brief Handles energy recharged. - * - * Implements DeviceEnergyModel::HandleEnergyChanged - */ - void HandleEnergyChanged (void); - - /** - * \brief Handles energy recharged. - * - * Implements DeviceEnergyModel::HandleEnergyRecharged - */ - void HandleEnergyRecharged (void); - - /** - * \returns Pointer to the PHY listener. - */ - LoraRadioEnergyModelPhyListener * GetPhyListener (void); - - -private: - void DoDispose (void); - - /** - * \returns Current draw of device, at current state. - * - * Implements DeviceEnergyModel::GetCurrentA. - */ - double DoGetCurrentA (void) const; - - /** - * \param state New state the radio device is currently in. - * - * Sets current state. This function is private so that only the energy model - * can change its own state. - */ - void SetLoraRadioState (const EndDeviceLoraPhy::State state); - - Ptr m_source; ///< energy source - - // Member variables for current draw in different radio modes. - double m_txCurrentA; ///< transmit current - double m_rxCurrentA; ///< receive current - double m_idleCurrentA; ///< idle current - double m_sleepCurrentA; ///< sleep current - // NOTICE VERY WELL: Current Model linear or constant as possible choices - Ptr m_txCurrentModel; ///< current model - - /// This variable keeps track of the total energy consumed by this model. - TracedValue m_totalEnergyConsumption; - - // State variables. - EndDeviceLoraPhy::State m_currentState; ///< current state the radio is in - Time m_lastUpdateTime; ///< time stamp of previous energy update - - uint8_t m_nPendingChangeState; ///< pending state change - bool m_isSupersededChangeState; ///< superseded change state - - /// Energy depletion callback - LoraRadioEnergyDepletionCallback m_energyDepletionCallback; - - /// Energy recharged callback - LoraRadioEnergyRechargedCallback m_energyRechargedCallback; - - /// EndDeviceLoraPhy listener - LoraRadioEnergyModelPhyListener *m_listener; + public: + /** + * Callback type for energy depletion handling. + */ + typedef Callback LoraRadioEnergyDepletionCallback; + + /** + * Callback type for energy recharged handling. + */ + typedef Callback LoraRadioEnergyRechargedCallback; + + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId(void); + LoraRadioEnergyModel(); + virtual ~LoraRadioEnergyModel(); + + /** + * \brief Sets pointer to EnergySouce installed on node. + * + * \param source Pointer to EnergySource installed on node. + * + * Implements DeviceEnergyModel::SetEnergySource. + */ + void SetEnergySource(Ptr source); + + /** + * \returns Total energy consumption of the wifi device. + * + * Implements DeviceEnergyModel::GetTotalEnergyConsumption. + */ + double GetTotalEnergyConsumption(void) const; + + // Setter & getters for state power consumption. + /** + * \brief Gets idle current. + * + * \returns idle current of the lora device. + */ + double GetStandbyCurrentA(void) const; + /** + * \brief Sets idle current. + * + * \param idleCurrentA the idle current + */ + void SetStandbyCurrentA(double idleCurrentA); + /** + * \brief Gets transmit current. + * + * \returns transmit current of the lora device. + */ + double GetTxCurrentA(void) const; + /** + * \brief Sets transmit current. + * + * \param txCurrentA the transmit current + */ + void SetTxCurrentA(double txCurrentA); + /** + * \brief Gets receive current. + * + * \returns receive current of the lora device. + */ + double GetRxCurrentA(void) const; + /** + * \brief Sets receive current. + * + * \param rxCurrentA the receive current + */ + void SetRxCurrentA(double rxCurrentA); + /** + * \brief Gets sleep current. + * + * \returns sleep current of the lora device. + */ + double GetSleepCurrentA(void) const; + /** + * \brief Sets sleep current. + * + * \param sleepCurrentA the sleep current + */ + void SetSleepCurrentA(double sleepCurrentA); + + /** + * \returns Current state. + */ + EndDeviceLoraPhy::State GetCurrentState(void) const; + + /** + * \param callback Callback function. + * + * Sets callback for energy depletion handling. + */ + void SetEnergyDepletionCallback(LoraRadioEnergyDepletionCallback callback); + + /** + * \param callback Callback function. + * + * Sets callback for energy recharged handling. + */ + void SetEnergyRechargedCallback(LoraRadioEnergyRechargedCallback callback); + + /** + * \param model the model used to compute the lora tx current. + */ + // NOTICE VERY WELL: Current Model linear or constant as possible choices + void SetTxCurrentModel(Ptr model); + + /** + * \brief Calls the CalcTxCurrent method of the tx current model to + * compute the tx current based on such model + * + * \param txPowerDbm the nominal tx power in dBm + */ + // NOTICE VERY WELL: Current Model linear or constant as possible choices + void SetTxCurrentFromModel(double txPowerDbm); + + /** + * \brief Changes state of the LoraRadioEnergyMode. + * + * \param newState New state the lora radio is in. + * + * Implements DeviceEnergyModel::ChangeState. + */ + void ChangeState(int newState); + + /** + * \brief Handles energy depletion. + * + * Implements DeviceEnergyModel::HandleEnergyDepletion + */ + void HandleEnergyDepletion(void); + + /** + * \brief Handles energy recharged. + * + * Implements DeviceEnergyModel::HandleEnergyChanged + */ + void HandleEnergyChanged(void); + + /** + * \brief Handles energy recharged. + * + * Implements DeviceEnergyModel::HandleEnergyRecharged + */ + void HandleEnergyRecharged(void); + + /** + * \returns Pointer to the PHY listener. + */ + LoraRadioEnergyModelPhyListener* GetPhyListener(void); + + private: + void DoDispose(void); + + /** + * \returns Current draw of device, at current state. + * + * Implements DeviceEnergyModel::GetCurrentA. + */ + double DoGetCurrentA(void) const; + + /** + * \param state New state the radio device is currently in. + * + * Sets current state. This function is private so that only the energy model + * can change its own state. + */ + void SetLoraRadioState(const EndDeviceLoraPhy::State state); + + Ptr m_source; ///< energy source + + // Member variables for current draw in different radio modes. + double m_txCurrentA; ///< transmit current + double m_rxCurrentA; ///< receive current + double m_idleCurrentA; ///< idle current + double m_sleepCurrentA; ///< sleep current + // NOTICE VERY WELL: Current Model linear or constant as possible choices + Ptr m_txCurrentModel; ///< current model + + /// This variable keeps track of the total energy consumed by this model. + TracedValue m_totalEnergyConsumption; + + // State variables. + EndDeviceLoraPhy::State m_currentState; ///< current state the radio is in + Time m_lastUpdateTime; ///< time stamp of previous energy update + + uint8_t m_nPendingChangeState; ///< pending state change + bool m_isSupersededChangeState; ///< superseded change state + + /// Energy depletion callback + LoraRadioEnergyDepletionCallback m_energyDepletionCallback; + + /// Energy recharged callback + LoraRadioEnergyRechargedCallback m_energyRechargedCallback; + + /// EndDeviceLoraPhy listener + LoraRadioEnergyModelPhyListener* m_listener; }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_RADIO_ENERGY_MODEL_H */ diff --git a/model/lora-tag.cc b/model/lora-tag.cc index 9c957ed18d..f9c2630886 100644 --- a/model/lora-tag.cc +++ b/model/lora-tag.cc @@ -18,139 +18,138 @@ * Author: Davide Magrin */ -#include "ns3/lora-tag.h" +#include "lora-tag.h" + #include "ns3/tag.h" #include "ns3/uinteger.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_OBJECT_ENSURE_REGISTERED (LoraTag); +NS_OBJECT_ENSURE_REGISTERED(LoraTag); TypeId -LoraTag::GetTypeId (void) +LoraTag::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LoraTag") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor () - ; - return tid; + static TypeId tid = + TypeId("ns3::LoraTag").SetParent().SetGroupName("lorawan").AddConstructor(); + return tid; } TypeId -LoraTag::GetInstanceTypeId (void) const +LoraTag::GetInstanceTypeId(void) const { - return GetTypeId (); + return GetTypeId(); } -LoraTag::LoraTag (uint8_t sf, uint8_t destroyedBy) : - m_sf (sf), - m_destroyedBy (destroyedBy), - m_receivePower (0), - m_dataRate (0), - m_frequency (0) +LoraTag::LoraTag(uint8_t sf, uint8_t destroyedBy) + : m_sf(sf), + m_destroyedBy(destroyedBy), + m_receivePower(0), + m_dataRate(0), + m_frequency(0) { } -LoraTag::~LoraTag () +LoraTag::~LoraTag() { } uint32_t -LoraTag::GetSerializedSize (void) const +LoraTag::GetSerializedSize(void) const { - // Each datum about a SF is 1 byte + receivePower (the size of a double) + - // frequency (the size of a double) - return 3 + 2 * sizeof(double); + // Each datum about a SF is 1 byte + receivePower (the size of a double) + + // frequency (the size of a double) + return 3 + 2 * sizeof(double); } void -LoraTag::Serialize (TagBuffer i) const +LoraTag::Serialize(TagBuffer i) const { - i.WriteU8 (m_sf); - i.WriteU8 (m_destroyedBy); - i.WriteDouble (m_receivePower); - i.WriteU8 (m_dataRate); - i.WriteDouble (m_frequency); + i.WriteU8(m_sf); + i.WriteU8(m_destroyedBy); + i.WriteDouble(m_receivePower); + i.WriteU8(m_dataRate); + i.WriteDouble(m_frequency); } void -LoraTag::Deserialize (TagBuffer i) +LoraTag::Deserialize(TagBuffer i) { - m_sf = i.ReadU8 (); - m_destroyedBy = i.ReadU8 (); - m_receivePower = i.ReadDouble (); - m_dataRate = i.ReadU8 (); - m_frequency = i.ReadDouble (); + m_sf = i.ReadU8(); + m_destroyedBy = i.ReadU8(); + m_receivePower = i.ReadDouble(); + m_dataRate = i.ReadU8(); + m_frequency = i.ReadDouble(); } void -LoraTag::Print (std::ostream &os) const +LoraTag::Print(std::ostream& os) const { - os << m_sf << " " << m_destroyedBy << " " << m_receivePower << " " << - m_dataRate; + os << m_sf << " " << m_destroyedBy << " " << m_receivePower << " " << m_dataRate; } uint8_t -LoraTag::GetSpreadingFactor () const +LoraTag::GetSpreadingFactor() const { - return m_sf; + return m_sf; } uint8_t -LoraTag::GetDestroyedBy () const +LoraTag::GetDestroyedBy() const { - return m_destroyedBy; + return m_destroyedBy; } double -LoraTag::GetReceivePower () const +LoraTag::GetReceivePower() const { - return m_receivePower; + return m_receivePower; } void -LoraTag::SetDestroyedBy (uint8_t sf) +LoraTag::SetDestroyedBy(uint8_t sf) { - m_destroyedBy = sf; + m_destroyedBy = sf; } void -LoraTag::SetSpreadingFactor (uint8_t sf) +LoraTag::SetSpreadingFactor(uint8_t sf) { - m_sf = sf; + m_sf = sf; } void -LoraTag::SetReceivePower (double receivePower) +LoraTag::SetReceivePower(double receivePower) { - m_receivePower = receivePower; + m_receivePower = receivePower; } void -LoraTag::SetFrequency (double frequency) +LoraTag::SetFrequency(double frequency) { - m_frequency = frequency; + m_frequency = frequency; } double -LoraTag::GetFrequency (void) +LoraTag::GetFrequency(void) { - return m_frequency; + return m_frequency; } uint8_t -LoraTag::GetDataRate (void) +LoraTag::GetDataRate(void) { - return m_dataRate; + return m_dataRate; } void -LoraTag::SetDataRate (uint8_t dataRate) +LoraTag::SetDataRate(uint8_t dataRate) { - m_dataRate = dataRate; + m_dataRate = dataRate; } -} +} // namespace lorawan } // namespace ns3 diff --git a/model/lora-tag.h b/model/lora-tag.h index 848e47acad..5aef3ba131 100644 --- a/model/lora-tag.h +++ b/model/lora-tag.h @@ -23,8 +23,10 @@ #include "ns3/tag.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Tag used to save various data about a packet, like its Spreading Factor and @@ -32,105 +34,105 @@ namespace lorawan { */ class LoraTag : public Tag { -public: - static TypeId GetTypeId (void); - virtual TypeId GetInstanceTypeId (void) const; - - /** - * Create a LoraTag with a given spreading factor and collision. - * - * \param sf The Spreading Factor. - * \param destroyedBy The SF this tag's packet was destroyed by. - */ - LoraTag (uint8_t sf = 0, uint8_t destroyedBy = 0); - - virtual ~LoraTag (); - - virtual void Serialize (TagBuffer i) const; - virtual void Deserialize (TagBuffer i); - virtual uint32_t GetSerializedSize () const; - virtual void Print (std::ostream &os) const; - - /** - * Read which Spreading Factor this packet was transmitted with. - * - * \return This tag's packet's SF. - */ - uint8_t GetSpreadingFactor () const; - - /** - * Read which Spreading Factor this packet was destroyed by. - * - * \return The SF this packet was destroyed by. - */ - uint8_t GetDestroyedBy () const; - - /** - * Read the power this packet arrived with. - * - * \return This tag's packet received power. - */ - double GetReceivePower () const; - - /** - * Set which Spreading Factor this packet was transmitted with. - * - * \param sf The Spreading Factor. - */ - void SetSpreadingFactor (uint8_t sf); - - /** - * Set which Spreading Factor this packet was destroyed by. - * - * \param sf The Spreading Factor. - */ - void SetDestroyedBy (uint8_t sf); - - /** - * Set the power this packet was received with. - * - * \param receivePower The power, in dBm. - */ - void SetReceivePower (double receivePower); - - /** - * Set the frequency of the packet. - * - * This value works in two ways: - * - It is used by the GW to signal to the NS the frequency of the uplink - packet - * - It is used by the NS to signal to the GW the freqeuncy of a downlink - packet - */ - void SetFrequency (double frequency); - - /** - * Get the frequency of the packet. - */ - double GetFrequency (void); - - /** - * Get the data rate for this packet. - * - * \return The data rate that needs to be employed for this packet. - */ - uint8_t GetDataRate (void); - - /** - * Set the data rate for this packet. - * - * \param dataRate The data rate. - */ - void SetDataRate (uint8_t dataRate); - -private: - uint8_t m_sf; //!< The Spreading Factor used by the packet. - uint8_t m_destroyedBy; //!< The Spreading Factor that destroyed the packet. - double m_receivePower; //!< The reception power of this packet. - uint8_t m_dataRate; //!< The Data Rate that needs to be used to send this - //!packet. - double m_frequency; //!< The frequency of this packet + public: + static TypeId GetTypeId(void); + virtual TypeId GetInstanceTypeId(void) const; + + /** + * Create a LoraTag with a given spreading factor and collision. + * + * \param sf The Spreading Factor. + * \param destroyedBy The SF this tag's packet was destroyed by. + */ + LoraTag(uint8_t sf = 0, uint8_t destroyedBy = 0); + + virtual ~LoraTag(); + + virtual void Serialize(TagBuffer i) const; + virtual void Deserialize(TagBuffer i); + virtual uint32_t GetSerializedSize() const; + virtual void Print(std::ostream& os) const; + + /** + * Read which Spreading Factor this packet was transmitted with. + * + * \return This tag's packet's SF. + */ + uint8_t GetSpreadingFactor() const; + + /** + * Read which Spreading Factor this packet was destroyed by. + * + * \return The SF this packet was destroyed by. + */ + uint8_t GetDestroyedBy() const; + + /** + * Read the power this packet arrived with. + * + * \return This tag's packet received power. + */ + double GetReceivePower() const; + + /** + * Set which Spreading Factor this packet was transmitted with. + * + * \param sf The Spreading Factor. + */ + void SetSpreadingFactor(uint8_t sf); + + /** + * Set which Spreading Factor this packet was destroyed by. + * + * \param sf The Spreading Factor. + */ + void SetDestroyedBy(uint8_t sf); + + /** + * Set the power this packet was received with. + * + * \param receivePower The power, in dBm. + */ + void SetReceivePower(double receivePower); + + /** + * Set the frequency of the packet. + * + * This value works in two ways: + * - It is used by the GW to signal to the NS the frequency of the uplink + packet + * - It is used by the NS to signal to the GW the freqeuncy of a downlink + packet + */ + void SetFrequency(double frequency); + + /** + * Get the frequency of the packet. + */ + double GetFrequency(void); + + /** + * Get the data rate for this packet. + * + * \return The data rate that needs to be employed for this packet. + */ + uint8_t GetDataRate(void); + + /** + * Set the data rate for this packet. + * + * \param dataRate The data rate. + */ + void SetDataRate(uint8_t dataRate); + + private: + uint8_t m_sf; //!< The Spreading Factor used by the packet. + uint8_t m_destroyedBy; //!< The Spreading Factor that destroyed the packet. + double m_receivePower; //!< The reception power of this packet. + uint8_t m_dataRate; //!< The Data Rate that needs to be used to send this + //! packet. + double m_frequency; //!< The frequency of this packet }; +} // namespace lorawan } // namespace ns3 -} #endif diff --git a/model/lora-tx-current-model.cc b/model/lora-tx-current-model.cc index 2c2417444f..b5466bd6e4 100644 --- a/model/lora-tx-current-model.cc +++ b/model/lora-tx-current-model.cc @@ -14,169 +14,172 @@ */ #include "lora-tx-current-model.h" -#include "ns3/log.h" -#include "ns3/double.h" + #include "lora-utils.h" -namespace ns3 { -namespace lorawan { +#include "ns3/double.h" +#include "ns3/log.h" + +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LoraTxCurrentModel"); +NS_LOG_COMPONENT_DEFINE("LoraTxCurrentModel"); -NS_OBJECT_ENSURE_REGISTERED (LoraTxCurrentModel); +NS_OBJECT_ENSURE_REGISTERED(LoraTxCurrentModel); TypeId -LoraTxCurrentModel::GetTypeId (void) +LoraTxCurrentModel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LoraTxCurrentModel") - .SetParent () - .SetGroupName ("Lora") - ; - return tid; + static TypeId tid = TypeId("ns3::LoraTxCurrentModel").SetParent().SetGroupName("Lora"); + return tid; } -LoraTxCurrentModel::LoraTxCurrentModel () +LoraTxCurrentModel::LoraTxCurrentModel() { } -LoraTxCurrentModel::~LoraTxCurrentModel () +LoraTxCurrentModel::~LoraTxCurrentModel() { } // Similarly to the wifi case -NS_OBJECT_ENSURE_REGISTERED (LinearLoraTxCurrentModel); +NS_OBJECT_ENSURE_REGISTERED(LinearLoraTxCurrentModel); TypeId -LinearLoraTxCurrentModel::GetTypeId (void) +LinearLoraTxCurrentModel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LinearLoraTxCurrentModel") - .SetParent () - .SetGroupName ("Lora") - .AddConstructor () - .AddAttribute ("Eta", "The efficiency of the power amplifier.", - DoubleValue (0.10), - MakeDoubleAccessor (&LinearLoraTxCurrentModel::SetEta, - &LinearLoraTxCurrentModel::GetEta), - MakeDoubleChecker ()) - .AddAttribute ("Voltage", "The supply voltage (in Volts).", - DoubleValue (3.3), - MakeDoubleAccessor (&LinearLoraTxCurrentModel::SetVoltage, - &LinearLoraTxCurrentModel::GetVoltage), - MakeDoubleChecker ()) - .AddAttribute ("StandbyCurrent", "The current in the STANDBY state (in Watts).", - DoubleValue (0.0014), // idle mode = 1.4mA - MakeDoubleAccessor (&LinearLoraTxCurrentModel::SetStandbyCurrent, - &LinearLoraTxCurrentModel::GetStandbyCurrent), - MakeDoubleChecker ()) - ; - return tid; + static TypeId tid = + TypeId("ns3::LinearLoraTxCurrentModel") + .SetParent() + .SetGroupName("Lora") + .AddConstructor() + .AddAttribute("Eta", + "The efficiency of the power amplifier.", + DoubleValue(0.10), + MakeDoubleAccessor(&LinearLoraTxCurrentModel::SetEta, + &LinearLoraTxCurrentModel::GetEta), + MakeDoubleChecker()) + .AddAttribute("Voltage", + "The supply voltage (in Volts).", + DoubleValue(3.3), + MakeDoubleAccessor(&LinearLoraTxCurrentModel::SetVoltage, + &LinearLoraTxCurrentModel::GetVoltage), + MakeDoubleChecker()) + .AddAttribute("StandbyCurrent", + "The current in the STANDBY state (in Watts).", + DoubleValue(0.0014), // idle mode = 1.4mA + MakeDoubleAccessor(&LinearLoraTxCurrentModel::SetStandbyCurrent, + &LinearLoraTxCurrentModel::GetStandbyCurrent), + MakeDoubleChecker()); + return tid; } -LinearLoraTxCurrentModel::LinearLoraTxCurrentModel () +LinearLoraTxCurrentModel::LinearLoraTxCurrentModel() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LinearLoraTxCurrentModel::~LinearLoraTxCurrentModel () +LinearLoraTxCurrentModel::~LinearLoraTxCurrentModel() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -LinearLoraTxCurrentModel::SetEta (double eta) +LinearLoraTxCurrentModel::SetEta(double eta) { - NS_LOG_FUNCTION (this << eta); - m_eta = eta; + NS_LOG_FUNCTION(this << eta); + m_eta = eta; } void -LinearLoraTxCurrentModel::SetVoltage (double voltage) +LinearLoraTxCurrentModel::SetVoltage(double voltage) { - NS_LOG_FUNCTION (this << voltage); - m_voltage = voltage; + NS_LOG_FUNCTION(this << voltage); + m_voltage = voltage; } void -LinearLoraTxCurrentModel::SetStandbyCurrent (double idleCurrent) +LinearLoraTxCurrentModel::SetStandbyCurrent(double idleCurrent) { - NS_LOG_FUNCTION (this << idleCurrent); - m_idleCurrent = idleCurrent; + NS_LOG_FUNCTION(this << idleCurrent); + m_idleCurrent = idleCurrent; } double -LinearLoraTxCurrentModel::GetEta (void) const +LinearLoraTxCurrentModel::GetEta(void) const { - return m_eta; + return m_eta; } double -LinearLoraTxCurrentModel::GetVoltage (void) const +LinearLoraTxCurrentModel::GetVoltage(void) const { - return m_voltage; + return m_voltage; } double -LinearLoraTxCurrentModel::GetStandbyCurrent (void) const +LinearLoraTxCurrentModel::GetStandbyCurrent(void) const { - return m_idleCurrent; + return m_idleCurrent; } double -LinearLoraTxCurrentModel::CalcTxCurrent (double txPowerDbm) const +LinearLoraTxCurrentModel::CalcTxCurrent(double txPowerDbm) const { - NS_LOG_FUNCTION (this << txPowerDbm); - return DbmToW (txPowerDbm) / (m_voltage * m_eta) + m_idleCurrent; + NS_LOG_FUNCTION(this << txPowerDbm); + return DbmToW(txPowerDbm) / (m_voltage * m_eta) + m_idleCurrent; } - -NS_OBJECT_ENSURE_REGISTERED (ConstantLoraTxCurrentModel); +NS_OBJECT_ENSURE_REGISTERED(ConstantLoraTxCurrentModel); TypeId -ConstantLoraTxCurrentModel::GetTypeId (void) +ConstantLoraTxCurrentModel::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::ConstantLoraTxCurrentModel") - .SetParent () - .SetGroupName ("Lora") - .AddConstructor () - .AddAttribute ("TxCurrent", - "The radio Tx current in Ampere.", - DoubleValue (0.028), // transmit at 0dBm = 28mA - MakeDoubleAccessor (&ConstantLoraTxCurrentModel::SetTxCurrent, - &ConstantLoraTxCurrentModel::GetTxCurrent), - MakeDoubleChecker ()) - ; - return tid; + static TypeId tid = + TypeId("ns3::ConstantLoraTxCurrentModel") + .SetParent() + .SetGroupName("Lora") + .AddConstructor() + .AddAttribute("TxCurrent", + "The radio Tx current in Ampere.", + DoubleValue(0.028), // transmit at 0dBm = 28mA + MakeDoubleAccessor(&ConstantLoraTxCurrentModel::SetTxCurrent, + &ConstantLoraTxCurrentModel::GetTxCurrent), + MakeDoubleChecker()); + return tid; } -ConstantLoraTxCurrentModel::ConstantLoraTxCurrentModel () +ConstantLoraTxCurrentModel::ConstantLoraTxCurrentModel() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -ConstantLoraTxCurrentModel::~ConstantLoraTxCurrentModel () +ConstantLoraTxCurrentModel::~ConstantLoraTxCurrentModel() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -ConstantLoraTxCurrentModel::SetTxCurrent (double txCurrent) +ConstantLoraTxCurrentModel::SetTxCurrent(double txCurrent) { - NS_LOG_FUNCTION (this << txCurrent); - m_txCurrent = txCurrent; + NS_LOG_FUNCTION(this << txCurrent); + m_txCurrent = txCurrent; } double -ConstantLoraTxCurrentModel::GetTxCurrent (void) const +ConstantLoraTxCurrentModel::GetTxCurrent(void) const { - return m_txCurrent; + return m_txCurrent; } double -ConstantLoraTxCurrentModel::CalcTxCurrent (double txPowerDbm) const +ConstantLoraTxCurrentModel::CalcTxCurrent(double txPowerDbm) const { - NS_LOG_FUNCTION (this << txPowerDbm); - return m_txCurrent; + NS_LOG_FUNCTION(this << txPowerDbm); + return m_txCurrent; } -} +} // namespace lorawan } // namespace ns3 diff --git a/model/lora-tx-current-model.h b/model/lora-tx-current-model.h index 8d6dfcb48a..fbfc830893 100644 --- a/model/lora-tx-current-model.h +++ b/model/lora-tx-current-model.h @@ -19,8 +19,10 @@ #include "ns3/object.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * \ingroup energy @@ -30,19 +32,19 @@ namespace lorawan { */ class LoraTxCurrentModel : public Object { -public: - static TypeId GetTypeId (void); - - LoraTxCurrentModel (); - virtual ~LoraTxCurrentModel (); - - /** - * Get the current for transmission at this power. - * - * \param txPowerDbm The nominal tx power in dBm - * \returns The transmit current (in Ampere) - */ - virtual double CalcTxCurrent (double txPowerDbm) const = 0; + public: + static TypeId GetTypeId(void); + + LoraTxCurrentModel(); + virtual ~LoraTxCurrentModel(); + + /** + * Get the current for transmission at this power. + * + * \param txPowerDbm The nominal tx power in dBm + * \returns The transmit current (in Ampere) + */ + virtual double CalcTxCurrent(double txPowerDbm) const = 0; }; /** @@ -51,88 +53,87 @@ class LoraTxCurrentModel : public Object */ class LinearLoraTxCurrentModel : public LoraTxCurrentModel { -public: - static TypeId GetTypeId (void); - - LinearLoraTxCurrentModel (); - virtual ~LinearLoraTxCurrentModel (); - - /** - * \param eta (dimension-less) - * - * Set the power amplifier efficiency. - */ - void SetEta (double eta); - - /** - * \param voltage (Volts) - * - * Set the supply voltage. - */ - void SetVoltage (double voltage); - - /** - * \param idleCurrent (Ampere) - * - * Set the current in the STANDBY state. - */ - void SetStandbyCurrent (double idleCurrent); - - /** - * \return the power amplifier efficiency. - */ - double GetEta (void) const; - - /** - * \return the supply voltage. - */ - double GetVoltage (void) const; - - /** - * \return the current in the STANDBY state. - */ - double GetStandbyCurrent (void) const; - - double CalcTxCurrent (double txPowerDbm) const; - -private: - double m_eta; //!< ETA - double m_voltage; //!< Voltage - double m_idleCurrent; //!< Standby current + public: + static TypeId GetTypeId(void); + + LinearLoraTxCurrentModel(); + virtual ~LinearLoraTxCurrentModel(); + + /** + * \param eta (dimension-less) + * + * Set the power amplifier efficiency. + */ + void SetEta(double eta); + + /** + * \param voltage (Volts) + * + * Set the supply voltage. + */ + void SetVoltage(double voltage); + + /** + * \param idleCurrent (Ampere) + * + * Set the current in the STANDBY state. + */ + void SetStandbyCurrent(double idleCurrent); + + /** + * \return the power amplifier efficiency. + */ + double GetEta(void) const; + + /** + * \return the supply voltage. + */ + double GetVoltage(void) const; + + /** + * \return the current in the STANDBY state. + */ + double GetStandbyCurrent(void) const; + + double CalcTxCurrent(double txPowerDbm) const; + + private: + double m_eta; //!< ETA + double m_voltage; //!< Voltage + double m_idleCurrent; //!< Standby current }; class ConstantLoraTxCurrentModel : public LoraTxCurrentModel { -public: - /** - * \brief Get the type ID. - * \return the object TypeId - */ - static TypeId GetTypeId (void); - - ConstantLoraTxCurrentModel (); - virtual ~ConstantLoraTxCurrentModel (); - - /** - * \param txCurrent (Ampere) - * - * Set the current in the TX state. - */ - void SetTxCurrent (double txCurrent); - - /** - * \return the current in the TX state. - */ - double GetTxCurrent (void) const; - - double CalcTxCurrent (double txPowerDbm) const; - - -private: - double m_txCurrent; + public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId(void); + + ConstantLoraTxCurrentModel(); + virtual ~ConstantLoraTxCurrentModel(); + + /** + * \param txCurrent (Ampere) + * + * Set the current in the TX state. + */ + void SetTxCurrent(double txCurrent); + + /** + * \return the current in the TX state. + */ + double GetTxCurrent(void) const; + + double CalcTxCurrent(double txPowerDbm) const; + + private: + double m_txCurrent; }; -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_TX_CURRENT_MODEL_H */ diff --git a/model/lora-utils.cc b/model/lora-utils.cc index 544d5c6f5d..37dabc9d8b 100644 --- a/model/lora-utils.cc +++ b/model/lora-utils.cc @@ -14,36 +14,39 @@ */ #include "lora-utils.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ double -DbToRatio (double dB) +DbToRatio(double dB) { - double ratio = std::pow (10.0, dB / 10.0); - return ratio; + double ratio = std::pow(10.0, dB / 10.0); + return ratio; } double -DbmToW (double dBm) +DbmToW(double dBm) { - double mW = std::pow (10.0, dBm / 10.0); - return mW / 1000.0; + double mW = std::pow(10.0, dBm / 10.0); + return mW / 1000.0; } double -WToDbm (double w) +WToDbm(double w) { - return 10.0 * std::log10 (w * 1000.0); + return 10.0 * std::log10(w * 1000.0); } double -RatioToDb (double ratio) +RatioToDb(double ratio) { - return 10.0 * std::log10 (ratio); + return 10.0 * std::log10(ratio); } -} -} //namespace ns3 +} // namespace lorawan +} // namespace ns3 diff --git a/model/lora-utils.h b/model/lora-utils.h index caa5a66646..db83b77c0a 100644 --- a/model/lora-utils.h +++ b/model/lora-utils.h @@ -19,8 +19,10 @@ #include "ns3/nstime.h" #include "ns3/uinteger.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Convert from dBm to Watts. @@ -29,7 +31,7 @@ namespace lorawan { * * \return the equivalent Watts for the given dBm */ -double DbmToW (double dbm); +double DbmToW(double dbm); /** * Convert from dB to ratio. * @@ -37,7 +39,7 @@ double DbmToW (double dbm); * * \return ratio */ -double DbToRatio (double db); +double DbToRatio(double db); /** * Convert from Watts to dBm. * @@ -45,7 +47,7 @@ double DbToRatio (double db); * * \return the equivalent dBm for the given Watts */ -double WToDbm (double w); +double WToDbm(double w); /** * Convert from ratio to dB. * @@ -53,9 +55,9 @@ double WToDbm (double w); * * \return dB */ -double RatioToDb (double ratio); +double RatioToDb(double ratio); -} // namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* LORA_UTILS_H */ diff --git a/model/lorawan-mac-header.cc b/model/lorawan-mac-header.cc index 48e9df0d53..4510654f1f 100644 --- a/model/lorawan-mac-header.cc +++ b/model/lorawan-mac-header.cc @@ -18,146 +18,147 @@ * Author: Davide Magrin */ -#include "ns3/lorawan-mac-header.h" +#include "lorawan-mac-header.h" + #include "ns3/log.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LorawanMacHeader"); +NS_LOG_COMPONENT_DEFINE("LorawanMacHeader"); -LorawanMacHeader::LorawanMacHeader () : m_major (0) +LorawanMacHeader::LorawanMacHeader() + : m_major(0) { } -LorawanMacHeader::~LorawanMacHeader () +LorawanMacHeader::~LorawanMacHeader() { } TypeId -LorawanMacHeader::GetTypeId (void) +LorawanMacHeader::GetTypeId(void) { - static TypeId tid = TypeId ("LorawanMacHeader") - .SetParent
() - .AddConstructor () - ; - return tid; + static TypeId tid = + TypeId("LorawanMacHeader").SetParent
().AddConstructor(); + return tid; } TypeId -LorawanMacHeader::GetInstanceTypeId (void) const +LorawanMacHeader::GetInstanceTypeId(void) const { - return GetTypeId (); + return GetTypeId(); } uint32_t -LorawanMacHeader::GetSerializedSize (void) const +LorawanMacHeader::GetSerializedSize(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return 1; // This header only consists in 8 bits + return 1; // This header only consists in 8 bits } void -LorawanMacHeader::Serialize (Buffer::Iterator start) const +LorawanMacHeader::Serialize(Buffer::Iterator start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // The header we need to fill - uint8_t header = 0; + // The header we need to fill + uint8_t header = 0; - // The MType - header |= m_mtype << 5; + // The MType + header |= m_mtype << 5; - // Do nothing for the bits that are RFU + // Do nothing for the bits that are RFU - // The major version bits - header |= m_major; + // The major version bits + header |= m_major; - // Write the byte - start.WriteU8 (header); + // Write the byte + start.WriteU8(header); - NS_LOG_DEBUG ("Serialization of MAC header: " << std::bitset<8> (header)); + NS_LOG_DEBUG("Serialization of MAC header: " << std::bitset<8>(header)); } uint32_t -LorawanMacHeader::Deserialize (Buffer::Iterator start) +LorawanMacHeader::Deserialize(Buffer::Iterator start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Save the byte on a temporary variable - uint8_t byte; - byte = start.ReadU8 (); + // Save the byte on a temporary variable + uint8_t byte; + byte = start.ReadU8(); - // Get the 2 least significant bits to have the Major - m_major = byte & 0b11; + // Get the 2 least significant bits to have the Major + m_major = byte & 0b11; - // Move the three most significant bits to the least significant positions - // to get the MType - m_mtype = byte >> 5; + // Move the three most significant bits to the least significant positions + // to get the MType + m_mtype = byte >> 5; - return 1; // the number of bytes consumed. + return 1; // the number of bytes consumed. } void -LorawanMacHeader::Print (std::ostream &os) const +LorawanMacHeader::Print(std::ostream& os) const { - os << "MessageType=" << unsigned(m_mtype) << std::endl; - os << "Major=" << unsigned(m_major) << std::endl; + os << "MessageType=" << unsigned(m_mtype) << std::endl; + os << "Major=" << unsigned(m_major) << std::endl; } void -LorawanMacHeader::SetMType (enum MType mtype) +LorawanMacHeader::SetMType(enum MType mtype) { - NS_LOG_FUNCTION (this << mtype); + NS_LOG_FUNCTION(this << mtype); - m_mtype = mtype; + m_mtype = mtype; } uint8_t -LorawanMacHeader::GetMType (void) const +LorawanMacHeader::GetMType(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_mtype; + return m_mtype; } void -LorawanMacHeader::SetMajor (uint8_t major) +LorawanMacHeader::SetMajor(uint8_t major) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - NS_ASSERT (0 <= major && major < 4); + NS_ASSERT(0 <= major && major < 4); - m_major = major; + m_major = major; } uint8_t -LorawanMacHeader::GetMajor (void) const +LorawanMacHeader::GetMajor(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_major; + return m_major; } bool -LorawanMacHeader::IsUplink (void) const +LorawanMacHeader::IsUplink(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return (m_mtype == JOIN_REQUEST) - || (m_mtype == UNCONFIRMED_DATA_UP) - || (m_mtype == CONFIRMED_DATA_UP); + return (m_mtype == JOIN_REQUEST) || (m_mtype == UNCONFIRMED_DATA_UP) || + (m_mtype == CONFIRMED_DATA_UP); } bool -LorawanMacHeader::IsConfirmed (void) const +LorawanMacHeader::IsConfirmed(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return (m_mtype == CONFIRMED_DATA_DOWN) - || (m_mtype == CONFIRMED_DATA_UP); -} -} + return (m_mtype == CONFIRMED_DATA_DOWN) || (m_mtype == CONFIRMED_DATA_UP); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lorawan-mac-header.h b/model/lorawan-mac-header.h index 8664c944a1..74595bed03 100644 --- a/model/lorawan-mac-header.h +++ b/model/lorawan-mac-header.h @@ -23,116 +23,118 @@ #include "ns3/header.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class represents the Mac header of a LoRaWAN packet. */ class LorawanMacHeader : public Header { -public: - /** - * The message type. - * - * The enum value corresponds to the value that will be written in the header - * by the Serialize method. - */ - enum MType - { - JOIN_REQUEST = 0, - JOIN_ACCEPT = 1, - UNCONFIRMED_DATA_UP = 2, - UNCONFIRMED_DATA_DOWN = 3, - CONFIRMED_DATA_UP = 4, - CONFIRMED_DATA_DOWN = 5, - PROPRIETARY = 7 - }; - - static TypeId GetTypeId (void); - - LorawanMacHeader (); - ~LorawanMacHeader (); - - // Pure virtual methods from Header that need to be implemented by this class - virtual TypeId GetInstanceTypeId (void) const; - virtual uint32_t GetSerializedSize (void) const; - - /** - * Serialize the header. - * - * See Page 15 of LoRaWAN specification for a representation of fields. - * - * \param start A pointer to the buffer that will be filled with the - * serialization. - */ - virtual void Serialize (Buffer::Iterator start) const; - - /** - * Deserialize the header. - * - * \param start A pointer to the buffer we need to deserialize. - * \return The number of consumed bytes. - */ - virtual uint32_t Deserialize (Buffer::Iterator start); - - /** - * Print the header in a human readable format. - * - * \param os The std::ostream on which to print the header. - */ - virtual void Print (std::ostream &os) const; - - /** - * Set the message type. - * - * \param mtype The message type of this header. - */ - void SetMType (enum MType mtype); - - /** - * Get the message type from the header. - * - * \return The uint8_t corresponding to this header's message type. - */ - uint8_t GetMType (void) const; - - /** - * Set the major version of this header. - * - * \param major The uint8_t corresponding to this header's major version. - */ - void SetMajor (uint8_t major); - - /** - * Get the major version from the header. - * - * \return The uint8_t corresponding to this header's major version. - */ - uint8_t GetMajor (void) const; - - /** - * Check whether this header is for an uplink message - * - * \return True if the message is meant to be sent from an ED to a GW, false - * otherwise. - */ - bool IsUplink (void) const; - - bool IsConfirmed (void) const; - -private: - /** - * The Message Type. - */ - uint8_t m_mtype; - - /** - * The major version this header is using. - */ - uint8_t m_major; + public: + /** + * The message type. + * + * The enum value corresponds to the value that will be written in the header + * by the Serialize method. + */ + enum MType + { + JOIN_REQUEST = 0, + JOIN_ACCEPT = 1, + UNCONFIRMED_DATA_UP = 2, + UNCONFIRMED_DATA_DOWN = 3, + CONFIRMED_DATA_UP = 4, + CONFIRMED_DATA_DOWN = 5, + PROPRIETARY = 7 + }; + + static TypeId GetTypeId(void); + + LorawanMacHeader(); + ~LorawanMacHeader(); + + // Pure virtual methods from Header that need to be implemented by this class + virtual TypeId GetInstanceTypeId(void) const; + virtual uint32_t GetSerializedSize(void) const; + + /** + * Serialize the header. + * + * See Page 15 of LoRaWAN specification for a representation of fields. + * + * \param start A pointer to the buffer that will be filled with the + * serialization. + */ + virtual void Serialize(Buffer::Iterator start) const; + + /** + * Deserialize the header. + * + * \param start A pointer to the buffer we need to deserialize. + * \return The number of consumed bytes. + */ + virtual uint32_t Deserialize(Buffer::Iterator start); + + /** + * Print the header in a human readable format. + * + * \param os The std::ostream on which to print the header. + */ + virtual void Print(std::ostream& os) const; + + /** + * Set the message type. + * + * \param mtype The message type of this header. + */ + void SetMType(enum MType mtype); + + /** + * Get the message type from the header. + * + * \return The uint8_t corresponding to this header's message type. + */ + uint8_t GetMType(void) const; + + /** + * Set the major version of this header. + * + * \param major The uint8_t corresponding to this header's major version. + */ + void SetMajor(uint8_t major); + + /** + * Get the major version from the header. + * + * \return The uint8_t corresponding to this header's major version. + */ + uint8_t GetMajor(void) const; + + /** + * Check whether this header is for an uplink message + * + * \return True if the message is meant to be sent from an ED to a GW, false + * otherwise. + */ + bool IsUplink(void) const; + + bool IsConfirmed(void) const; + + private: + /** + * The Message Type. + */ + uint8_t m_mtype; + + /** + * The major version this header is using. + */ + uint8_t m_major; }; -} +} // namespace lorawan -} +} // namespace ns3 #endif diff --git a/model/lorawan-mac.cc b/model/lorawan-mac.cc index 6ee9dd50f2..16dd4e8d99 100644 --- a/model/lorawan-mac.cc +++ b/model/lorawan-mac.cc @@ -18,173 +18,177 @@ * Author: Davide Magrin */ -#include "ns3/lorawan-mac.h" +#include "lorawan-mac.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("LorawanMac"); +NS_LOG_COMPONENT_DEFINE("LorawanMac"); -NS_OBJECT_ENSURE_REGISTERED (LorawanMac); +NS_OBJECT_ENSURE_REGISTERED(LorawanMac); TypeId -LorawanMac::GetTypeId (void) +LorawanMac::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LorawanMac") - .SetParent () - .SetGroupName ("lorawan") - .AddTraceSource ("SentNewPacket", - "Trace source indicating a new packet " - "arrived at the MAC layer", - MakeTraceSourceAccessor (&LorawanMac::m_sentNewPacket), - "ns3::Packet::TracedCallback") - .AddTraceSource ("ReceivedPacket", - "Trace source indicating a packet " - "was correctly received at the MAC layer", - MakeTraceSourceAccessor (&LorawanMac::m_receivedPacket), - "ns3::Packet::TracedCallback") - .AddTraceSource ("CannotSendBecauseDutyCycle", - "Trace source indicating a packet " - "could not be sent immediately because of duty cycle limitations", - MakeTraceSourceAccessor (&LorawanMac::m_cannotSendBecauseDutyCycle), - "ns3::Packet::TracedCallback"); - return tid; + static TypeId tid = + TypeId("ns3::LorawanMac") + .SetParent() + .SetGroupName("lorawan") + .AddTraceSource("SentNewPacket", + "Trace source indicating a new packet " + "arrived at the MAC layer", + MakeTraceSourceAccessor(&LorawanMac::m_sentNewPacket), + "ns3::Packet::TracedCallback") + .AddTraceSource("ReceivedPacket", + "Trace source indicating a packet " + "was correctly received at the MAC layer", + MakeTraceSourceAccessor(&LorawanMac::m_receivedPacket), + "ns3::Packet::TracedCallback") + .AddTraceSource("CannotSendBecauseDutyCycle", + "Trace source indicating a packet " + "could not be sent immediately because of duty cycle limitations", + MakeTraceSourceAccessor(&LorawanMac::m_cannotSendBecauseDutyCycle), + "ns3::Packet::TracedCallback"); + return tid; } -LorawanMac::LorawanMac () +LorawanMac::LorawanMac() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -LorawanMac::~LorawanMac () +LorawanMac::~LorawanMac() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } void -LorawanMac::SetDevice (Ptr device) +LorawanMac::SetDevice(Ptr device) { - m_device = device; + m_device = device; } Ptr -LorawanMac::GetDevice (void) +LorawanMac::GetDevice(void) { - return m_device; + return m_device; } Ptr -LorawanMac::GetPhy (void) +LorawanMac::GetPhy(void) { - return m_phy; + return m_phy; } void -LorawanMac::SetPhy (Ptr phy) +LorawanMac::SetPhy(Ptr phy) { - // Set the phy - m_phy = phy; + // Set the phy + m_phy = phy; - // Connect the receive callbacks - m_phy->SetReceiveOkCallback (MakeCallback (&LorawanMac::Receive, this)); - m_phy->SetReceiveFailedCallback (MakeCallback (&LorawanMac::FailedReception, this)); - m_phy->SetTxFinishedCallback (MakeCallback (&LorawanMac::TxFinished, this)); + // Connect the receive callbacks + m_phy->SetReceiveOkCallback(MakeCallback(&LorawanMac::Receive, this)); + m_phy->SetReceiveFailedCallback(MakeCallback(&LorawanMac::FailedReception, this)); + m_phy->SetTxFinishedCallback(MakeCallback(&LorawanMac::TxFinished, this)); } LogicalLoraChannelHelper -LorawanMac::GetLogicalLoraChannelHelper (void) +LorawanMac::GetLogicalLoraChannelHelper(void) { - return m_channelHelper; + return m_channelHelper; } void -LorawanMac::SetLogicalLoraChannelHelper (LogicalLoraChannelHelper helper) +LorawanMac::SetLogicalLoraChannelHelper(LogicalLoraChannelHelper helper) { - m_channelHelper = helper; + m_channelHelper = helper; } uint8_t -LorawanMac::GetSfFromDataRate (uint8_t dataRate) +LorawanMac::GetSfFromDataRate(uint8_t dataRate) { - NS_LOG_FUNCTION (this << unsigned(dataRate)); + NS_LOG_FUNCTION(this << unsigned(dataRate)); - // Check we are in range - if (dataRate >= m_sfForDataRate.size ()) + // Check we are in range + if (dataRate >= m_sfForDataRate.size()) { - return 0; + return 0; } - return m_sfForDataRate.at (dataRate); + return m_sfForDataRate.at(dataRate); } double -LorawanMac::GetBandwidthFromDataRate (uint8_t dataRate) +LorawanMac::GetBandwidthFromDataRate(uint8_t dataRate) { - NS_LOG_FUNCTION (this << unsigned(dataRate)); + NS_LOG_FUNCTION(this << unsigned(dataRate)); - // Check we are in range - if (dataRate > m_bandwidthForDataRate.size ()) + // Check we are in range + if (dataRate > m_bandwidthForDataRate.size()) { - return 0; + return 0; } - return m_bandwidthForDataRate.at (dataRate); + return m_bandwidthForDataRate.at(dataRate); } double -LorawanMac::GetDbmForTxPower (uint8_t txPower) +LorawanMac::GetDbmForTxPower(uint8_t txPower) { - NS_LOG_FUNCTION (this << unsigned (txPower)); + NS_LOG_FUNCTION(this << unsigned(txPower)); - if (txPower > m_txDbmForTxPower.size ()) + if (txPower > m_txDbmForTxPower.size()) { - return 0; + return 0; } - return m_txDbmForTxPower.at (txPower); + return m_txDbmForTxPower.at(txPower); } void -LorawanMac::SetSfForDataRate (std::vector sfForDataRate) +LorawanMac::SetSfForDataRate(std::vector sfForDataRate) { - m_sfForDataRate = sfForDataRate; + m_sfForDataRate = sfForDataRate; } void -LorawanMac::SetBandwidthForDataRate (std::vector bandwidthForDataRate) +LorawanMac::SetBandwidthForDataRate(std::vector bandwidthForDataRate) { - m_bandwidthForDataRate = bandwidthForDataRate; + m_bandwidthForDataRate = bandwidthForDataRate; } void -LorawanMac::SetMaxAppPayloadForDataRate (std::vector maxAppPayloadForDataRate) +LorawanMac::SetMaxAppPayloadForDataRate(std::vector maxAppPayloadForDataRate) { - m_maxAppPayloadForDataRate = maxAppPayloadForDataRate; + m_maxAppPayloadForDataRate = maxAppPayloadForDataRate; } void -LorawanMac::SetTxDbmForTxPower (std::vector txDbmForTxPower) +LorawanMac::SetTxDbmForTxPower(std::vector txDbmForTxPower) { - m_txDbmForTxPower = txDbmForTxPower; + m_txDbmForTxPower = txDbmForTxPower; } void -LorawanMac::SetNPreambleSymbols (int nPreambleSymbols) +LorawanMac::SetNPreambleSymbols(int nPreambleSymbols) { - m_nPreambleSymbols = nPreambleSymbols; + m_nPreambleSymbols = nPreambleSymbols; } int -LorawanMac::GetNPreambleSymbols (void) +LorawanMac::GetNPreambleSymbols(void) { - return m_nPreambleSymbols; + return m_nPreambleSymbols; } void -LorawanMac::SetReplyDataRateMatrix (ReplyDataRateMatrix replyDataRateMatrix) +LorawanMac::SetReplyDataRateMatrix(ReplyDataRateMatrix replyDataRateMatrix) { - m_replyDataRateMatrix = replyDataRateMatrix; -} -} + m_replyDataRateMatrix = replyDataRateMatrix; } +} // namespace lorawan +} // namespace ns3 diff --git a/model/lorawan-mac.h b/model/lorawan-mac.h index 92045b5aa8..3121c58df9 100644 --- a/model/lorawan-mac.h +++ b/model/lorawan-mac.h @@ -21,14 +21,18 @@ #ifndef LORAWAN_MAC_H #define LORAWAN_MAC_H +#include "logical-lora-channel-helper.h" +#include "lora-phy.h" + #include "ns3/object.h" -#include "ns3/logical-lora-channel-helper.h" #include "ns3/packet.h" -#include "ns3/lora-phy.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraPhy; @@ -41,244 +45,243 @@ class LoraPhy; */ class LorawanMac : public Object { -public: - static TypeId GetTypeId (void); - - LorawanMac (); - virtual ~LorawanMac (); - - typedef std::array, 8> ReplyDataRateMatrix; - - /** - * Set the underlying PHY layer - * - * \param phy the phy layer - */ - void SetPhy (Ptr phy); - - /** - * Get the underlying PHY layer - * - * \return The PHY layer that this MAC is connected to. - */ - Ptr GetPhy (void); - - /** - * Send a packet. - * - * \param packet The packet to send. - */ - virtual void Send (Ptr packet) = 0; - - /** - * Receive a packet from the lower layer. - * - * \param packet the received packet - */ - virtual void Receive (Ptr packet) = 0; - - /** - * Function called by lower layers to inform this layer that reception of a - * packet we were locked on failed. - * - * \param packet the packet we failed to receive - */ - virtual void FailedReception (Ptr packet) = 0; - - /** - * Perform actions after sending a packet. - * - * \param packet The packet that just finished transmission. - */ - virtual void TxFinished (Ptr packet) = 0; - - /** - * Set the device this MAC layer is installed on. - * - * \param device The NetDevice this MAC layer will refer to. - */ - void SetDevice (Ptr device); - - /** - * Get the device this MAC layer is installed on. - * - * \return The NetDevice this MAC layer will refer to. - */ - Ptr GetDevice (void); - - /** - * Get the logical lora channel helper associated with this MAC. - * - * \return The instance of LogicalLoraChannelHelper that this MAC is using. - */ - LogicalLoraChannelHelper GetLogicalLoraChannelHelper (void); - - /** - * Set the LogicalLoraChannelHelper this MAC instance will use. - * - * \param helper The instance of the helper to use. - */ - void SetLogicalLoraChannelHelper (LogicalLoraChannelHelper helper); - - /** - * Get the SF corresponding to a data rate, based on this MAC's region. - * - * \param dataRate The Data Rate we need to convert to a Spreading Factor - * value. - * \return The SF that corresponds to a Data Rate in this MAC's region, or 0 - * if the dataRate is not valid. - */ - uint8_t GetSfFromDataRate (uint8_t dataRate); - - /** - * Get the BW corresponding to a data rate, based on this MAC's region - * - * \param dataRate The Data Rate we need to convert to a bandwidth value. - * \return The bandwidth that corresponds to the parameter Data Rate in this - * MAC's region, or 0 if the dataRate is not valid. - */ - double GetBandwidthFromDataRate (uint8_t dataRate); - - /** - * Get the transmission power in dBm that corresponds, in this region, to the - * encoded 8-bit txPower. - * - * \param txPower The 8-bit encoded txPower to convert. - * - * \return The corresponding transmission power in dBm, or 0 if the encoded - * power was not recognized as valid. - */ - double GetDbmForTxPower (uint8_t txPower); - - /** - * Set the vector to use to check up correspondence between SF and DataRate. - * - * \param sfForDataRate A vector that contains at position i the SF that - * should correspond to DR i. - */ - void SetSfForDataRate (std::vector sfForDataRate); - - /** - * Set the vector to use to check up correspondence between bandwidth and - * DataRate. - * - * \param bandwidthForDataRate A vector that contains at position i the - * bandwidth that should correspond to DR i in this MAC's region. - */ - void SetBandwidthForDataRate (std::vector bandwidthForDataRate); - - /** - * Set the maximum App layer payload for a set DataRate. - * - * \param maxAppPayloadForDataRate A vector that contains at position i the - * maximum Application layer payload that should correspond to DR i in this - * MAC's region. - */ - void SetMaxAppPayloadForDataRate (std::vector - maxAppPayloadForDataRate); - - /** - * Set the vector to use to check up which transmission power in Dbm - * corresponds to a certain TxPower value in this MAC's region. - * - * \param txDbmForTxPower A vector that contains at position i the - * transmission power in dBm that should correspond to a TXPOWER value of i in - * this MAC's region. - */ - void SetTxDbmForTxPower (std::vector txDbmForTxPower); - - /** - * Set the matrix to use when deciding with which DataRate to respond. Region - * based. - * - * \param replyDataRateMatrix A matrix containing the reply DataRates, based - * on the sending DataRate and on the value of the RX1DROffset parameter. - */ - void SetReplyDataRateMatrix (ReplyDataRateMatrix replyDataRateMatrix); - - /** - * Set the number of PHY preamble symbols this MAC is set to use. - * - * \param nPreambleSymbols The number of preamble symbols to use (typically 8). - */ - void SetNPreambleSymbols (int nPreambleSymbols); - - /** - * Get the number of PHY preamble symbols this MAC is set to use. - * - * \return The number of preamble symbols to use (typically 8). - */ - int GetNPreambleSymbols (void); - -protected: - /** - * The trace source that is fired when a packet cannot be sent because of duty - * cycle limitations. - * - * \see class CallBackTraceSource - */ - TracedCallback > m_cannotSendBecauseDutyCycle; - - /** - * Trace source that is fired when a packet reaches the MAC layer. - */ - TracedCallback > m_receivedPacket; - - /** - * Trace source that is fired when a new APP layer packet arrives at the MAC - * layer. - */ - TracedCallback > m_sentNewPacket; - - /** - * The PHY instance that sits under this MAC layer. - */ - Ptr m_phy; - - /** - * The device this MAC layer is installed on. - */ - Ptr m_device; - - /** - * The LogicalLoraChannelHelper instance that is assigned to this MAC. - */ - LogicalLoraChannelHelper m_channelHelper; - - /** - * A vector holding the SF each Data Rate corresponds to. - */ - std::vector m_sfForDataRate; - - /** - * A vector holding the bandwidth each Data Rate corresponds to. - */ - std::vector m_bandwidthForDataRate; - - /** - * A vector holding the maximum app payload size that corresponds to a - * certain DataRate. - */ - std::vector m_maxAppPayloadForDataRate; - - /** - * The number of symbols to use in the PHY preamble. - */ - int m_nPreambleSymbols; - - /** - * A vector holding the power that corresponds to a certain TxPower value. - */ - std::vector m_txDbmForTxPower; - - /** - * The matrix that decides the DR the GW will use in a reply based on the ED's - * sending DR and on the value of the RX1DROffset parameter. - */ - ReplyDataRateMatrix m_replyDataRateMatrix; + public: + static TypeId GetTypeId(void); + + LorawanMac(); + virtual ~LorawanMac(); + + typedef std::array, 8> ReplyDataRateMatrix; + + /** + * Set the underlying PHY layer + * + * \param phy the phy layer + */ + void SetPhy(Ptr phy); + + /** + * Get the underlying PHY layer + * + * \return The PHY layer that this MAC is connected to. + */ + Ptr GetPhy(void); + + /** + * Send a packet. + * + * \param packet The packet to send. + */ + virtual void Send(Ptr packet) = 0; + + /** + * Receive a packet from the lower layer. + * + * \param packet the received packet + */ + virtual void Receive(Ptr packet) = 0; + + /** + * Function called by lower layers to inform this layer that reception of a + * packet we were locked on failed. + * + * \param packet the packet we failed to receive + */ + virtual void FailedReception(Ptr packet) = 0; + + /** + * Perform actions after sending a packet. + * + * \param packet The packet that just finished transmission. + */ + virtual void TxFinished(Ptr packet) = 0; + + /** + * Set the device this MAC layer is installed on. + * + * \param device The NetDevice this MAC layer will refer to. + */ + void SetDevice(Ptr device); + + /** + * Get the device this MAC layer is installed on. + * + * \return The NetDevice this MAC layer will refer to. + */ + Ptr GetDevice(void); + + /** + * Get the logical lora channel helper associated with this MAC. + * + * \return The instance of LogicalLoraChannelHelper that this MAC is using. + */ + LogicalLoraChannelHelper GetLogicalLoraChannelHelper(void); + + /** + * Set the LogicalLoraChannelHelper this MAC instance will use. + * + * \param helper The instance of the helper to use. + */ + void SetLogicalLoraChannelHelper(LogicalLoraChannelHelper helper); + + /** + * Get the SF corresponding to a data rate, based on this MAC's region. + * + * \param dataRate The Data Rate we need to convert to a Spreading Factor + * value. + * \return The SF that corresponds to a Data Rate in this MAC's region, or 0 + * if the dataRate is not valid. + */ + uint8_t GetSfFromDataRate(uint8_t dataRate); + + /** + * Get the BW corresponding to a data rate, based on this MAC's region + * + * \param dataRate The Data Rate we need to convert to a bandwidth value. + * \return The bandwidth that corresponds to the parameter Data Rate in this + * MAC's region, or 0 if the dataRate is not valid. + */ + double GetBandwidthFromDataRate(uint8_t dataRate); + + /** + * Get the transmission power in dBm that corresponds, in this region, to the + * encoded 8-bit txPower. + * + * \param txPower The 8-bit encoded txPower to convert. + * + * \return The corresponding transmission power in dBm, or 0 if the encoded + * power was not recognized as valid. + */ + double GetDbmForTxPower(uint8_t txPower); + + /** + * Set the vector to use to check up correspondence between SF and DataRate. + * + * \param sfForDataRate A vector that contains at position i the SF that + * should correspond to DR i. + */ + void SetSfForDataRate(std::vector sfForDataRate); + + /** + * Set the vector to use to check up correspondence between bandwidth and + * DataRate. + * + * \param bandwidthForDataRate A vector that contains at position i the + * bandwidth that should correspond to DR i in this MAC's region. + */ + void SetBandwidthForDataRate(std::vector bandwidthForDataRate); + + /** + * Set the maximum App layer payload for a set DataRate. + * + * \param maxAppPayloadForDataRate A vector that contains at position i the + * maximum Application layer payload that should correspond to DR i in this + * MAC's region. + */ + void SetMaxAppPayloadForDataRate(std::vector maxAppPayloadForDataRate); + + /** + * Set the vector to use to check up which transmission power in Dbm + * corresponds to a certain TxPower value in this MAC's region. + * + * \param txDbmForTxPower A vector that contains at position i the + * transmission power in dBm that should correspond to a TXPOWER value of i in + * this MAC's region. + */ + void SetTxDbmForTxPower(std::vector txDbmForTxPower); + + /** + * Set the matrix to use when deciding with which DataRate to respond. Region + * based. + * + * \param replyDataRateMatrix A matrix containing the reply DataRates, based + * on the sending DataRate and on the value of the RX1DROffset parameter. + */ + void SetReplyDataRateMatrix(ReplyDataRateMatrix replyDataRateMatrix); + + /** + * Set the number of PHY preamble symbols this MAC is set to use. + * + * \param nPreambleSymbols The number of preamble symbols to use (typically 8). + */ + void SetNPreambleSymbols(int nPreambleSymbols); + + /** + * Get the number of PHY preamble symbols this MAC is set to use. + * + * \return The number of preamble symbols to use (typically 8). + */ + int GetNPreambleSymbols(void); + + protected: + /** + * The trace source that is fired when a packet cannot be sent because of duty + * cycle limitations. + * + * \see class CallBackTraceSource + */ + TracedCallback> m_cannotSendBecauseDutyCycle; + + /** + * Trace source that is fired when a packet reaches the MAC layer. + */ + TracedCallback> m_receivedPacket; + + /** + * Trace source that is fired when a new APP layer packet arrives at the MAC + * layer. + */ + TracedCallback> m_sentNewPacket; + + /** + * The PHY instance that sits under this MAC layer. + */ + Ptr m_phy; + + /** + * The device this MAC layer is installed on. + */ + Ptr m_device; + + /** + * The LogicalLoraChannelHelper instance that is assigned to this MAC. + */ + LogicalLoraChannelHelper m_channelHelper; + + /** + * A vector holding the SF each Data Rate corresponds to. + */ + std::vector m_sfForDataRate; + + /** + * A vector holding the bandwidth each Data Rate corresponds to. + */ + std::vector m_bandwidthForDataRate; + + /** + * A vector holding the maximum app payload size that corresponds to a + * certain DataRate. + */ + std::vector m_maxAppPayloadForDataRate; + + /** + * The number of symbols to use in the PHY preamble. + */ + int m_nPreambleSymbols; + + /** + * A vector holding the power that corresponds to a certain TxPower value. + */ + std::vector m_txDbmForTxPower; + + /** + * The matrix that decides the DR the GW will use in a reply based on the ED's + * sending DR and on the value of the RX1DROffset parameter. + */ + ReplyDataRateMatrix m_replyDataRateMatrix; }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* LORAWAN_MAC_H */ diff --git a/model/mac-command.cc b/model/mac-command.cc index bbb49eef62..25db741e80 100644 --- a/model/mac-command.cc +++ b/model/mac-command.cc @@ -18,1208 +18,1203 @@ * Author: Davide Magrin */ -#include "ns3/mac-command.h" +#include "mac-command.h" + #include "ns3/log.h" + #include #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("MacCommand"); +NS_LOG_COMPONENT_DEFINE("MacCommand"); -NS_OBJECT_ENSURE_REGISTERED (MacCommand); +NS_OBJECT_ENSURE_REGISTERED(MacCommand); TypeId -MacCommand::GetTypeId (void) +MacCommand::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::MacCommand") - .SetParent () - .SetGroupName ("lorawan") - ; - return tid; + static TypeId tid = TypeId("ns3::MacCommand").SetParent().SetGroupName("lorawan"); + return tid; } -MacCommand::MacCommand () +MacCommand::MacCommand() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } -MacCommand::~MacCommand () +MacCommand::~MacCommand() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } enum MacCommandType -MacCommand::GetCommandType (void) const +MacCommand::GetCommandType(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_commandType; + return m_commandType; } uint8_t -MacCommand::GetSerializedSize (void) const +MacCommand::GetSerializedSize(void) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_serializedSize; + return m_serializedSize; } uint8_t -MacCommand::GetCIDFromMacCommand (enum MacCommandType commandType) +MacCommand::GetCIDFromMacCommand(enum MacCommandType commandType) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - switch (commandType) + switch (commandType) { - case (INVALID): - { + case (INVALID): { return 0x0; - } + } case (LINK_CHECK_REQ): - case (LINK_CHECK_ANS): - { + case (LINK_CHECK_ANS): { return 0x02; - } + } case (LINK_ADR_REQ): - case (LINK_ADR_ANS): - { + case (LINK_ADR_ANS): { return 0x03; - } + } case (DUTY_CYCLE_REQ): - case (DUTY_CYCLE_ANS): - { + case (DUTY_CYCLE_ANS): { return 0x04; - } + } case (RX_PARAM_SETUP_REQ): - case (RX_PARAM_SETUP_ANS): - { + case (RX_PARAM_SETUP_ANS): { return 0x05; - } + } case (DEV_STATUS_REQ): - case (DEV_STATUS_ANS): - { + case (DEV_STATUS_ANS): { return 0x06; - } + } case (NEW_CHANNEL_REQ): - case (NEW_CHANNEL_ANS): - { + case (NEW_CHANNEL_ANS): { return 0x07; - } + } case (RX_TIMING_SETUP_REQ): - case (RX_TIMING_SETUP_ANS): - { + case (RX_TIMING_SETUP_ANS): { return 0x08; - } + } case (TX_PARAM_SETUP_REQ): - case (TX_PARAM_SETUP_ANS): - { + case (TX_PARAM_SETUP_ANS): { return 0x09; - } + } case (DL_CHANNEL_REQ): - case (DL_CHANNEL_ANS): - { + case (DL_CHANNEL_ANS): { return 0x0A; - } } - return 0; + } + return 0; } ////////////////// // LinkCheckReq // ////////////////// -LinkCheckReq::LinkCheckReq () +LinkCheckReq::LinkCheckReq() { - NS_LOG_FUNCTION_NOARGS (); - m_commandType = LINK_CHECK_REQ; - m_serializedSize = 1; + NS_LOG_FUNCTION_NOARGS(); + m_commandType = LINK_CHECK_REQ; + m_serializedSize = 1; } -LinkCheckReq::~LinkCheckReq () +LinkCheckReq::~LinkCheckReq() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -LinkCheckReq::Serialize (Buffer::Iterator &start) const +LinkCheckReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID and we're done - uint8_t cid = GetCIDFromMacCommand (m_commandType); - start.WriteU8 (cid); - NS_LOG_DEBUG ("Serialized LinkCheckReq: " << unsigned (cid)); + // Write the CID and we're done + uint8_t cid = GetCIDFromMacCommand(m_commandType); + start.WriteU8(cid); + NS_LOG_DEBUG("Serialized LinkCheckReq: " << unsigned(cid)); } uint8_t -LinkCheckReq::Deserialize (Buffer::Iterator &start) +LinkCheckReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Read the CID - start.ReadU8 (); + // Read the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -LinkCheckReq::Print (std::ostream &os) const +LinkCheckReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "LinkCheckReq" << std::endl; + os << "LinkCheckReq" << std::endl; } ////////////////// // LinkCheckAns // ////////////////// -LinkCheckAns::LinkCheckAns () : - m_margin (0), - m_gwCnt (0) +LinkCheckAns::LinkCheckAns() + : m_margin(0), + m_gwCnt(0) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = LINK_CHECK_ANS; - m_serializedSize = 3; + m_commandType = LINK_CHECK_ANS; + m_serializedSize = 3; } -LinkCheckAns::LinkCheckAns (uint8_t margin, uint8_t gwCnt) : - m_margin (margin), - m_gwCnt (gwCnt) +LinkCheckAns::LinkCheckAns(uint8_t margin, uint8_t gwCnt) + : m_margin(margin), + m_gwCnt(gwCnt) { - NS_LOG_FUNCTION (this << unsigned(margin) << unsigned(gwCnt)); + NS_LOG_FUNCTION(this << unsigned(margin) << unsigned(gwCnt)); - m_commandType = LINK_CHECK_ANS; - m_serializedSize = 3; + m_commandType = LINK_CHECK_ANS; + m_serializedSize = 3; } void -LinkCheckAns::Serialize (Buffer::Iterator &start) const +LinkCheckAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - // Write the margin - start.WriteU8 (m_margin); - // Write the gwCnt - start.WriteU8 (m_gwCnt); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + // Write the margin + start.WriteU8(m_margin); + // Write the gwCnt + start.WriteU8(m_gwCnt); } uint8_t -LinkCheckAns::Deserialize (Buffer::Iterator &start) +LinkCheckAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - m_margin = start.ReadU8 (); - m_gwCnt = start.ReadU8 (); - return m_serializedSize; + // Consume the CID + start.ReadU8(); + m_margin = start.ReadU8(); + m_gwCnt = start.ReadU8(); + return m_serializedSize; } void -LinkCheckAns::Print (std::ostream &os) const +LinkCheckAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "LinkCheckAns" << std::endl; - os << "margin: " << unsigned (m_margin) << std::endl; - os << "gwCnt: " << unsigned (m_gwCnt) << std::endl; + os << "LinkCheckAns" << std::endl; + os << "margin: " << unsigned(m_margin) << std::endl; + os << "gwCnt: " << unsigned(m_gwCnt) << std::endl; } void -LinkCheckAns::SetMargin (uint8_t margin) +LinkCheckAns::SetMargin(uint8_t margin) { - NS_LOG_FUNCTION (this << unsigned (margin)); + NS_LOG_FUNCTION(this << unsigned(margin)); - m_margin = margin; + m_margin = margin; } uint8_t -LinkCheckAns::GetMargin (void) const +LinkCheckAns::GetMargin(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_margin; + return m_margin; } void -LinkCheckAns::SetGwCnt (uint8_t gwCnt) +LinkCheckAns::SetGwCnt(uint8_t gwCnt) { - NS_LOG_FUNCTION (this << unsigned (gwCnt)); + NS_LOG_FUNCTION(this << unsigned(gwCnt)); - m_gwCnt = gwCnt; + m_gwCnt = gwCnt; } uint8_t -LinkCheckAns::GetGwCnt (void) const +LinkCheckAns::GetGwCnt(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_gwCnt; + return m_gwCnt; } void -LinkCheckAns::IncrementGwCnt (void) +LinkCheckAns::IncrementGwCnt(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_gwCnt++; + m_gwCnt++; } //////////////// // LinkAdrReq // //////////////// -LinkAdrReq::LinkAdrReq () +LinkAdrReq::LinkAdrReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = LINK_ADR_REQ; - m_serializedSize = 5; + m_commandType = LINK_ADR_REQ; + m_serializedSize = 5; } -LinkAdrReq::LinkAdrReq (uint8_t dataRate, uint8_t txPower, uint16_t channelMask, - uint8_t chMaskCntl, uint8_t nbRep) : - m_dataRate (dataRate), - m_txPower (txPower), - m_channelMask (channelMask), - m_chMaskCntl (chMaskCntl), - m_nbRep (nbRep) +LinkAdrReq::LinkAdrReq(uint8_t dataRate, + uint8_t txPower, + uint16_t channelMask, + uint8_t chMaskCntl, + uint8_t nbRep) + : m_dataRate(dataRate), + m_txPower(txPower), + m_channelMask(channelMask), + m_chMaskCntl(chMaskCntl), + m_nbRep(nbRep) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = LINK_ADR_REQ; - m_serializedSize = 5; + m_commandType = LINK_ADR_REQ; + m_serializedSize = 5; } void -LinkAdrReq::Serialize (Buffer::Iterator &start) const +LinkAdrReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - start.WriteU8 (m_dataRate << 4 | (m_txPower & 0b1111)); - start.WriteU16 (m_channelMask); - start.WriteU8 (m_chMaskCntl << 4 | (m_nbRep & 0b1111)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + start.WriteU8(m_dataRate << 4 | (m_txPower & 0b1111)); + start.WriteU16(m_channelMask); + start.WriteU8(m_chMaskCntl << 4 | (m_nbRep & 0b1111)); } uint8_t -LinkAdrReq::Deserialize (Buffer::Iterator &start) +LinkAdrReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - uint8_t firstByte = start.ReadU8 (); - m_dataRate = firstByte >> 4; - m_txPower = firstByte & 0b1111; - m_channelMask = start.ReadU16 (); - uint8_t fourthByte = start.ReadU8 (); - m_chMaskCntl = fourthByte >> 4; - m_nbRep = fourthByte & 0b1111; + // Consume the CID + start.ReadU8(); + uint8_t firstByte = start.ReadU8(); + m_dataRate = firstByte >> 4; + m_txPower = firstByte & 0b1111; + m_channelMask = start.ReadU16(); + uint8_t fourthByte = start.ReadU8(); + m_chMaskCntl = fourthByte >> 4; + m_nbRep = fourthByte & 0b1111; - return m_serializedSize; + return m_serializedSize; } void -LinkAdrReq::Print (std::ostream &os) const +LinkAdrReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "LinkAdrReq" << std::endl; - os << "dataRate: " << unsigned (m_dataRate) << std::endl; - os << "txPower: " << unsigned (m_txPower) << std::endl; - os << "channelMask: " << std::bitset<16> (m_channelMask) << std::endl; - os << "chMaskCntl: " << unsigned (m_chMaskCntl) << std::endl; - os << "nbRep: " << unsigned (m_nbRep) << std::endl; + os << "LinkAdrReq" << std::endl; + os << "dataRate: " << unsigned(m_dataRate) << std::endl; + os << "txPower: " << unsigned(m_txPower) << std::endl; + os << "channelMask: " << std::bitset<16>(m_channelMask) << std::endl; + os << "chMaskCntl: " << unsigned(m_chMaskCntl) << std::endl; + os << "nbRep: " << unsigned(m_nbRep) << std::endl; } uint8_t -LinkAdrReq::GetDataRate (void) +LinkAdrReq::GetDataRate(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_dataRate; + return m_dataRate; } uint8_t -LinkAdrReq::GetTxPower (void) +LinkAdrReq::GetTxPower(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_txPower; + return m_txPower; } std::list -LinkAdrReq::GetEnabledChannelsList (void) +LinkAdrReq::GetEnabledChannelsList(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - std::list channelIndices; - for (int i = 0; i < 16; i++) + std::list channelIndices; + for (int i = 0; i < 16; i++) { - if (m_channelMask & (0b1 << i)) // Take channel mask's i-th bit + if (m_channelMask & (0b1 << i)) // Take channel mask's i-th bit { - NS_LOG_DEBUG ("Adding channel index " << i); - channelIndices.push_back (i); + NS_LOG_DEBUG("Adding channel index " << i); + channelIndices.push_back(i); } } - return channelIndices; + return channelIndices; } int -LinkAdrReq::GetRepetitions (void) +LinkAdrReq::GetRepetitions(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_nbRep; + return m_nbRep; } + //////////////// // LinkAdrAns // //////////////// -LinkAdrAns::LinkAdrAns () +LinkAdrAns::LinkAdrAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = LINK_ADR_ANS; - m_serializedSize = 2; + m_commandType = LINK_ADR_ANS; + m_serializedSize = 2; } -LinkAdrAns::LinkAdrAns (bool powerAck, bool dataRateAck, bool channelMaskAck) : - m_powerAck (powerAck), - m_dataRateAck (dataRateAck), - m_channelMaskAck (channelMaskAck) +LinkAdrAns::LinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck) + : m_powerAck(powerAck), + m_dataRateAck(dataRateAck), + m_channelMaskAck(channelMaskAck) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = LINK_ADR_ANS; - m_serializedSize = 2; + m_commandType = LINK_ADR_ANS; + m_serializedSize = 2; } void -LinkAdrAns::Serialize (Buffer::Iterator &start) const +LinkAdrAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - // We can assume that true will be converted to 1 and that false will be - // converted to 0 on any C++ compiler - start.WriteU8 ((uint8_t (m_powerAck) << 2) | (uint8_t (m_dataRateAck) << 1) | - uint8_t (m_channelMaskAck)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + // We can assume that true will be converted to 1 and that false will be + // converted to 0 on any C++ compiler + start.WriteU8((uint8_t(m_powerAck) << 2) | (uint8_t(m_dataRateAck) << 1) | + uint8_t(m_channelMaskAck)); } uint8_t -LinkAdrAns::Deserialize (Buffer::Iterator &start) +LinkAdrAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - uint8_t byte = start.ReadU8 (); + uint8_t byte = start.ReadU8(); - m_powerAck = byte & 0b100; - m_dataRateAck = byte & 0b10; - m_channelMaskAck = byte & 0b1; + m_powerAck = byte & 0b100; + m_dataRateAck = byte & 0b10; + m_channelMaskAck = byte & 0b1; - return m_serializedSize; + return m_serializedSize; } void -LinkAdrAns::Print (std::ostream &os) const +LinkAdrAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "LinkAdrAns" << std::endl; + os << "LinkAdrAns" << std::endl; } ////////////////// // DutyCycleReq // ////////////////// -DutyCycleReq::DutyCycleReq () +DutyCycleReq::DutyCycleReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DUTY_CYCLE_REQ; - m_serializedSize = 2; + m_commandType = DUTY_CYCLE_REQ; + m_serializedSize = 2; } -DutyCycleReq::DutyCycleReq (uint8_t dutyCycle) : - m_maxDCycle (dutyCycle) +DutyCycleReq::DutyCycleReq(uint8_t dutyCycle) + : m_maxDCycle(dutyCycle) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DUTY_CYCLE_REQ; - m_serializedSize = 2; + m_commandType = DUTY_CYCLE_REQ; + m_serializedSize = 2; } void -DutyCycleReq::Serialize (Buffer::Iterator &start) const +DutyCycleReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - start.WriteU8 (m_maxDCycle); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + start.WriteU8(m_maxDCycle); } uint8_t -DutyCycleReq::Deserialize (Buffer::Iterator &start) +DutyCycleReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - m_maxDCycle = start.ReadU8 (); + // Consume the CID + start.ReadU8(); + m_maxDCycle = start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -DutyCycleReq::Print (std::ostream &os) const +DutyCycleReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "DutyCycleReq" << std::endl; - os << "maxDCycle: " << unsigned (m_maxDCycle) << std::endl; - os << "maxDCycle (fraction): " << GetMaximumAllowedDutyCycle () << std::endl; + os << "DutyCycleReq" << std::endl; + os << "maxDCycle: " << unsigned(m_maxDCycle) << std::endl; + os << "maxDCycle (fraction): " << GetMaximumAllowedDutyCycle() << std::endl; } double -DutyCycleReq::GetMaximumAllowedDutyCycle (void) const +DutyCycleReq::GetMaximumAllowedDutyCycle(void) const { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Check if we need to turn off completely - if (m_maxDCycle == 255) + // Check if we need to turn off completely + if (m_maxDCycle == 255) { - return 0; + return 0; } - if (m_maxDCycle == 0) + if (m_maxDCycle == 0) { - return 1; + return 1; } - return 1 / std::pow (2,double(m_maxDCycle)); + return 1 / std::pow(2, double(m_maxDCycle)); } ////////////////// // DutyCycleAns // ////////////////// -DutyCycleAns::DutyCycleAns () +DutyCycleAns::DutyCycleAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DUTY_CYCLE_ANS; - m_serializedSize = 1; + m_commandType = DUTY_CYCLE_ANS; + m_serializedSize = 1; } void -DutyCycleAns::Serialize (Buffer::Iterator &start) const +DutyCycleAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -DutyCycleAns::Deserialize (Buffer::Iterator &start) +DutyCycleAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - return m_serializedSize; + // Consume the CID + start.ReadU8(); + return m_serializedSize; } void -DutyCycleAns::Print (std::ostream &os) const +DutyCycleAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "DutyCycleAns" << std::endl; + os << "DutyCycleAns" << std::endl; } ////////////////// // RxParamSetupReq // ////////////////// -RxParamSetupReq::RxParamSetupReq () +RxParamSetupReq::RxParamSetupReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = RX_PARAM_SETUP_REQ; - m_serializedSize = 5; + m_commandType = RX_PARAM_SETUP_REQ; + m_serializedSize = 5; } -RxParamSetupReq::RxParamSetupReq (uint8_t rx1DrOffset, uint8_t rx2DataRate, - double frequency) : - m_rx1DrOffset (rx1DrOffset), - m_rx2DataRate (rx2DataRate), - m_frequency (frequency) +RxParamSetupReq::RxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency) + : m_rx1DrOffset(rx1DrOffset), + m_rx2DataRate(rx2DataRate), + m_frequency(frequency) { - NS_LOG_FUNCTION (this << unsigned (rx1DrOffset) << unsigned (rx2DataRate) << - frequency); + NS_LOG_FUNCTION(this << unsigned(rx1DrOffset) << unsigned(rx2DataRate) << frequency); - if ((rx1DrOffset & 0b11111000) != 0) + if ((rx1DrOffset & 0b11111000) != 0) { - NS_LOG_WARN ("Warning: received an rx1DrOffset greater than 7. Actual value will be different."); + NS_LOG_WARN( + "Warning: received an rx1DrOffset greater than 7. Actual value will be different."); } - if ((rx2DataRate & 0b11110000) != 0) + if ((rx2DataRate & 0b11110000) != 0) { - NS_LOG_WARN ("Warning: received a rx2DataRate greater than 15. Actual value will be different."); + NS_LOG_WARN( + "Warning: received a rx2DataRate greater than 15. Actual value will be different."); } - m_commandType = RX_PARAM_SETUP_REQ; - m_serializedSize = 5; + m_commandType = RX_PARAM_SETUP_REQ; + m_serializedSize = 5; } void -RxParamSetupReq::Serialize (Buffer::Iterator &start) const +RxParamSetupReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - // Data serialization - start.WriteU8 ((m_rx1DrOffset & 0b111) << 4 | (m_rx2DataRate & 0b1111)); - uint32_t encodedFrequency = uint32_t (m_frequency / 100); - NS_LOG_DEBUG (unsigned (encodedFrequency)); - NS_LOG_DEBUG (std::bitset<32> (encodedFrequency)); - start.WriteU8 ((encodedFrequency & 0xff0000) >> 16); // Most significant byte - start.WriteU8 ((encodedFrequency & 0xff00) >> 8); // Middle byte - start.WriteU8 (encodedFrequency & 0xff); // Least significant byte + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + // Data serialization + start.WriteU8((m_rx1DrOffset & 0b111) << 4 | (m_rx2DataRate & 0b1111)); + uint32_t encodedFrequency = uint32_t(m_frequency / 100); + NS_LOG_DEBUG(unsigned(encodedFrequency)); + NS_LOG_DEBUG(std::bitset<32>(encodedFrequency)); + start.WriteU8((encodedFrequency & 0xff0000) >> 16); // Most significant byte + start.WriteU8((encodedFrequency & 0xff00) >> 8); // Middle byte + start.WriteU8(encodedFrequency & 0xff); // Least significant byte } uint8_t -RxParamSetupReq::Deserialize (Buffer::Iterator &start) +RxParamSetupReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - // Data serialization - uint8_t firstByte = start.ReadU8 (); - m_rx1DrOffset = (firstByte & 0b1110000) >> 4; - m_rx2DataRate = firstByte & 0b1111; - uint32_t secondByte = start.ReadU8 (); - uint32_t thirdByte = start.ReadU8 (); - uint32_t fourthByte = start.ReadU8 (); - uint32_t encodedFrequency = (secondByte << 16) | (thirdByte << 8) | fourthByte; - NS_LOG_DEBUG (std::bitset<32> (encodedFrequency)); - m_frequency = double(encodedFrequency) * 100; + // Consume the CID + start.ReadU8(); + // Data serialization + uint8_t firstByte = start.ReadU8(); + m_rx1DrOffset = (firstByte & 0b1110000) >> 4; + m_rx2DataRate = firstByte & 0b1111; + uint32_t secondByte = start.ReadU8(); + uint32_t thirdByte = start.ReadU8(); + uint32_t fourthByte = start.ReadU8(); + uint32_t encodedFrequency = (secondByte << 16) | (thirdByte << 8) | fourthByte; + NS_LOG_DEBUG(std::bitset<32>(encodedFrequency)); + m_frequency = double(encodedFrequency) * 100; - return m_serializedSize; + return m_serializedSize; } void -RxParamSetupReq::Print (std::ostream &os) const +RxParamSetupReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "RxParamSetupReq" << std::endl; - os << "rx1DrOffset: " << unsigned( m_rx1DrOffset) << std::endl; - os << "rx2DataRate: " << unsigned( m_rx2DataRate) << std::endl; - os << "frequency: " << m_frequency << std::endl; + os << "RxParamSetupReq" << std::endl; + os << "rx1DrOffset: " << unsigned(m_rx1DrOffset) << std::endl; + os << "rx2DataRate: " << unsigned(m_rx2DataRate) << std::endl; + os << "frequency: " << m_frequency << std::endl; } uint8_t -RxParamSetupReq::GetRx1DrOffset (void) +RxParamSetupReq::GetRx1DrOffset(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_rx1DrOffset; + return m_rx1DrOffset; } + uint8_t -RxParamSetupReq::GetRx2DataRate (void) +RxParamSetupReq::GetRx2DataRate(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_rx2DataRate; + return m_rx2DataRate; } + double -RxParamSetupReq::GetFrequency (void) +RxParamSetupReq::GetFrequency(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_frequency; + return m_frequency; } ///////////////////// // RxParamSetupAns // ///////////////////// -RxParamSetupAns::RxParamSetupAns () +RxParamSetupAns::RxParamSetupAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = RX_PARAM_SETUP_ANS; - m_serializedSize = 2; + m_commandType = RX_PARAM_SETUP_ANS; + m_serializedSize = 2; } -RxParamSetupAns::RxParamSetupAns (bool rx1DrOffsetAck, bool rx2DataRateAck, - bool channelAck) : - m_rx1DrOffsetAck (rx1DrOffsetAck), - m_rx2DataRateAck (rx2DataRateAck), - m_channelAck (channelAck) +RxParamSetupAns::RxParamSetupAns(bool rx1DrOffsetAck, bool rx2DataRateAck, bool channelAck) + : m_rx1DrOffsetAck(rx1DrOffsetAck), + m_rx2DataRateAck(rx2DataRateAck), + m_channelAck(channelAck) { - NS_LOG_FUNCTION (this << rx1DrOffsetAck << rx2DataRateAck << channelAck); + NS_LOG_FUNCTION(this << rx1DrOffsetAck << rx2DataRateAck << channelAck); - m_commandType = RX_PARAM_SETUP_ANS; - m_serializedSize = 2; + m_commandType = RX_PARAM_SETUP_ANS; + m_serializedSize = 2; } void -RxParamSetupAns::Serialize (Buffer::Iterator &start) const +RxParamSetupAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); - - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - // Data serialization - start.WriteU8 (uint8_t (m_rx1DrOffsetAck) << 2 | - uint8_t (m_rx2DataRateAck) << 1 | - uint8_t (m_channelAck)); + NS_LOG_FUNCTION_NOARGS(); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + // Data serialization + start.WriteU8(uint8_t(m_rx1DrOffsetAck) << 2 | uint8_t(m_rx2DataRateAck) << 1 | + uint8_t(m_channelAck)); } uint8_t -RxParamSetupAns::Deserialize (Buffer::Iterator &start) +RxParamSetupAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - uint8_t byte = start.ReadU8 (); + uint8_t byte = start.ReadU8(); - m_rx1DrOffsetAck = (byte & 0b100) >> 2; - m_rx2DataRateAck = (byte & 0b10) >> 1; - m_channelAck = byte & 0b1; + m_rx1DrOffsetAck = (byte & 0b100) >> 2; + m_rx2DataRateAck = (byte & 0b10) >> 1; + m_channelAck = byte & 0b1; - return m_serializedSize; + return m_serializedSize; } void -RxParamSetupAns::Print (std::ostream &os) const +RxParamSetupAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "RxParamSetupAns" << std::endl; - os << "m_rx1DrOffsetAck: " << m_rx1DrOffsetAck << std::endl; - os << "m_rx2DataRateAck: " << m_rx2DataRateAck << std::endl; - os << "m_channelAck: " << m_channelAck << std::endl; + os << "RxParamSetupAns" << std::endl; + os << "m_rx1DrOffsetAck: " << m_rx1DrOffsetAck << std::endl; + os << "m_rx2DataRateAck: " << m_rx2DataRateAck << std::endl; + os << "m_channelAck: " << m_channelAck << std::endl; } ////////////////// // DevStatusReq // ////////////////// -DevStatusReq::DevStatusReq () +DevStatusReq::DevStatusReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_REQ; - m_serializedSize = 1; + m_commandType = DEV_STATUS_REQ; + m_serializedSize = 1; } void -DevStatusReq::Serialize (Buffer::Iterator &start) const +DevStatusReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -DevStatusReq::Deserialize (Buffer::Iterator &start) +DevStatusReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -DevStatusReq::Print (std::ostream &os) const +DevStatusReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "DevStatusReq" << std::endl; + os << "DevStatusReq" << std::endl; } ////////////////// // DevStatusAns // ////////////////// -DevStatusAns::DevStatusAns () +DevStatusAns::DevStatusAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_ANS; - m_serializedSize = 3; + m_commandType = DEV_STATUS_ANS; + m_serializedSize = 3; } -DevStatusAns::DevStatusAns (uint8_t battery, uint8_t margin) : - m_battery (battery), - m_margin (margin) +DevStatusAns::DevStatusAns(uint8_t battery, uint8_t margin) + : m_battery(battery), + m_margin(margin) { - NS_LOG_FUNCTION (this << unsigned (battery) << unsigned (margin)); + NS_LOG_FUNCTION(this << unsigned(battery) << unsigned(margin)); - m_commandType = DEV_STATUS_ANS; - m_serializedSize = 3; + m_commandType = DEV_STATUS_ANS; + m_serializedSize = 3; } void -DevStatusAns::Serialize (Buffer::Iterator &start) const +DevStatusAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - start.WriteU8 (m_battery); - start.WriteU8 (m_margin); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + start.WriteU8(m_battery); + start.WriteU8(m_margin); } uint8_t -DevStatusAns::Deserialize (Buffer::Iterator &start) +DevStatusAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - m_battery = start.ReadU8 (); - m_margin = start.ReadU8 () & 0b111111; + // Consume the CID + start.ReadU8(); + m_battery = start.ReadU8(); + m_margin = start.ReadU8() & 0b111111; - return m_serializedSize; + return m_serializedSize; } void -DevStatusAns::Print (std::ostream &os) const +DevStatusAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "DevStatusAns" << std::endl; - os << "Battery: " << unsigned (m_battery) << std::endl; - os << "Margin: " << unsigned (m_margin) << std::endl; + os << "DevStatusAns" << std::endl; + os << "Battery: " << unsigned(m_battery) << std::endl; + os << "Margin: " << unsigned(m_margin) << std::endl; } uint8_t -DevStatusAns::GetBattery (void) +DevStatusAns::GetBattery(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_battery; + return m_battery; } uint8_t -DevStatusAns::GetMargin (void) +DevStatusAns::GetMargin(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_margin; + return m_margin; } ////////////////// // NewChannelReq // ////////////////// -NewChannelReq::NewChannelReq () +NewChannelReq::NewChannelReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = NEW_CHANNEL_REQ; - m_serializedSize = 6; + m_commandType = NEW_CHANNEL_REQ; + m_serializedSize = 6; } -NewChannelReq::NewChannelReq (uint8_t chIndex, double frequency, - uint8_t minDataRate, uint8_t maxDataRate) : - m_chIndex (chIndex), - m_frequency (frequency), - m_minDataRate (minDataRate), - m_maxDataRate (maxDataRate) +NewChannelReq::NewChannelReq(uint8_t chIndex, + double frequency, + uint8_t minDataRate, + uint8_t maxDataRate) + : m_chIndex(chIndex), + m_frequency(frequency), + m_minDataRate(minDataRate), + m_maxDataRate(maxDataRate) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = NEW_CHANNEL_REQ; - m_serializedSize = 6; + m_commandType = NEW_CHANNEL_REQ; + m_serializedSize = 6; } void -NewChannelReq::Serialize (Buffer::Iterator &start) const +NewChannelReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); - start.WriteU8 (m_chIndex); - uint32_t encodedFrequency = uint32_t (m_frequency / 100); - start.WriteU8 ((encodedFrequency & 0xff0000) >> 16); - start.WriteU8 ((encodedFrequency & 0xff00) >> 8); - start.WriteU8 (encodedFrequency & 0xff); - start.WriteU8 ((m_maxDataRate << 4) | (m_minDataRate & 0xf)); + start.WriteU8(m_chIndex); + uint32_t encodedFrequency = uint32_t(m_frequency / 100); + start.WriteU8((encodedFrequency & 0xff0000) >> 16); + start.WriteU8((encodedFrequency & 0xff00) >> 8); + start.WriteU8(encodedFrequency & 0xff); + start.WriteU8((m_maxDataRate << 4) | (m_minDataRate & 0xf)); } uint8_t -NewChannelReq::Deserialize (Buffer::Iterator &start) +NewChannelReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - // Read the data - m_chIndex = start.ReadU8 (); - uint32_t encodedFrequency = 0; - encodedFrequency |= uint32_t (start.ReadU16 ()) << 8; - encodedFrequency |= uint32_t (start.ReadU8 ()); - m_frequency = double (encodedFrequency) * 100; - uint8_t dataRateByte = start.ReadU8 (); - m_maxDataRate = dataRateByte >> 4; - m_minDataRate = dataRateByte & 0xf; + // Consume the CID + start.ReadU8(); + // Read the data + m_chIndex = start.ReadU8(); + uint32_t encodedFrequency = 0; + encodedFrequency |= uint32_t(start.ReadU16()) << 8; + encodedFrequency |= uint32_t(start.ReadU8()); + m_frequency = double(encodedFrequency) * 100; + uint8_t dataRateByte = start.ReadU8(); + m_maxDataRate = dataRateByte >> 4; + m_minDataRate = dataRateByte & 0xf; - return m_serializedSize; + return m_serializedSize; } void -NewChannelReq::Print (std::ostream &os) const +NewChannelReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); - - os << "NewChannelReq" << std::endl; + NS_LOG_FUNCTION_NOARGS(); + os << "NewChannelReq" << std::endl; } uint8_t -NewChannelReq::GetChannelIndex (void) +NewChannelReq::GetChannelIndex(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_chIndex; + return m_chIndex; } double -NewChannelReq::GetFrequency (void) +NewChannelReq::GetFrequency(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_frequency; + return m_frequency; } uint8_t -NewChannelReq::GetMinDataRate (void) +NewChannelReq::GetMinDataRate(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_minDataRate; + return m_minDataRate; } uint8_t -NewChannelReq::GetMaxDataRate (void) +NewChannelReq::GetMaxDataRate(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - return m_maxDataRate; + return m_maxDataRate; } /////////////////// // NewChannelAns // /////////////////// -NewChannelAns::NewChannelAns () +NewChannelAns::NewChannelAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = NEW_CHANNEL_ANS; - m_serializedSize = 2; + m_commandType = NEW_CHANNEL_ANS; + m_serializedSize = 2; } -NewChannelAns::NewChannelAns (bool dataRateRangeOk, bool channelFrequencyOk) : - m_dataRateRangeOk (dataRateRangeOk), - m_channelFrequencyOk (channelFrequencyOk) +NewChannelAns::NewChannelAns(bool dataRateRangeOk, bool channelFrequencyOk) + : m_dataRateRangeOk(dataRateRangeOk), + m_channelFrequencyOk(channelFrequencyOk) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = NEW_CHANNEL_ANS; - m_serializedSize = 2; + m_commandType = NEW_CHANNEL_ANS; + m_serializedSize = 2; } void -NewChannelAns::Serialize (Buffer::Iterator &start) const +NewChannelAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); - start.WriteU8 ((uint8_t (m_dataRateRangeOk) << 1) | - uint8_t (m_channelFrequencyOk)); + start.WriteU8((uint8_t(m_dataRateRangeOk) << 1) | uint8_t(m_channelFrequencyOk)); } uint8_t -NewChannelAns::Deserialize (Buffer::Iterator &start) +NewChannelAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - // Read the data - uint8_t byte = start.ReadU8 (); - m_dataRateRangeOk = (byte & 0b10) >> 1; - m_channelFrequencyOk = (byte & 0b1); + // Consume the CID + start.ReadU8(); + // Read the data + uint8_t byte = start.ReadU8(); + m_dataRateRangeOk = (byte & 0b10) >> 1; + m_channelFrequencyOk = (byte & 0b1); - return m_serializedSize; + return m_serializedSize; } void -NewChannelAns::Print (std::ostream &os) const +NewChannelAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "NewChannelAns" << std::endl; - os << "DataRateRangeOk: " << m_dataRateRangeOk << std::endl; - os << "ChannelFrequencyOk: " << m_channelFrequencyOk << std::endl; + os << "NewChannelAns" << std::endl; + os << "DataRateRangeOk: " << m_dataRateRangeOk << std::endl; + os << "ChannelFrequencyOk: " << m_channelFrequencyOk << std::endl; } ////////////////////// // RxTimingSetupReq // ////////////////////// -RxTimingSetupReq::RxTimingSetupReq () +RxTimingSetupReq::RxTimingSetupReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = RX_TIMING_SETUP_REQ; - m_serializedSize = 2; + m_commandType = RX_TIMING_SETUP_REQ; + m_serializedSize = 2; } -RxTimingSetupReq::RxTimingSetupReq (uint8_t delay) : - m_delay (delay) +RxTimingSetupReq::RxTimingSetupReq(uint8_t delay) + : m_delay(delay) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = RX_TIMING_SETUP_REQ; - m_serializedSize = 2; + m_commandType = RX_TIMING_SETUP_REQ; + m_serializedSize = 2; } void -RxTimingSetupReq::Serialize (Buffer::Iterator &start) const +RxTimingSetupReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); - // Write the data - start.WriteU8 (m_delay & 0xf); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); + // Write the data + start.WriteU8(m_delay & 0xf); } uint8_t -RxTimingSetupReq::Deserialize (Buffer::Iterator &start) +RxTimingSetupReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); - // Read the data - m_delay = start.ReadU8 () & 0xf; + // Consume the CID + start.ReadU8(); + // Read the data + m_delay = start.ReadU8() & 0xf; - return m_serializedSize; + return m_serializedSize; } void -RxTimingSetupReq::Print (std::ostream &os) const +RxTimingSetupReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "RxTimingSetupReq" << std::endl; + os << "RxTimingSetupReq" << std::endl; } Time -RxTimingSetupReq::GetDelay (void) +RxTimingSetupReq::GetDelay(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - if (m_delay == 0) + if (m_delay == 0) { - return Seconds (1); + return Seconds(1); } - return Seconds (m_delay); + return Seconds(m_delay); } + ////////////////// // RxTimingSetupAns // ////////////////// -RxTimingSetupAns::RxTimingSetupAns () +RxTimingSetupAns::RxTimingSetupAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_REQ; - m_serializedSize = 1; + m_commandType = DEV_STATUS_REQ; + m_serializedSize = 1; } void -RxTimingSetupAns::Serialize (Buffer::Iterator &start) const +RxTimingSetupAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -RxTimingSetupAns::Deserialize (Buffer::Iterator &start) +RxTimingSetupAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -RxTimingSetupAns::Print (std::ostream &os) const +RxTimingSetupAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "RxTimingSetupAns" << std::endl; + os << "RxTimingSetupAns" << std::endl; } ////////////////// // DlChannelAns // ////////////////// -DlChannelAns::DlChannelAns () +DlChannelAns::DlChannelAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_REQ; - m_serializedSize = 1; + m_commandType = DEV_STATUS_REQ; + m_serializedSize = 1; } void -DlChannelAns::Serialize (Buffer::Iterator &start) const +DlChannelAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -DlChannelAns::Deserialize (Buffer::Iterator &start) +DlChannelAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -DlChannelAns::Print (std::ostream &os) const +DlChannelAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "DlChannelAns" << std::endl; + os << "DlChannelAns" << std::endl; } ////////////////// // TxParamSetupReq // ////////////////// -TxParamSetupReq::TxParamSetupReq () +TxParamSetupReq::TxParamSetupReq() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_REQ; - m_serializedSize = 1; + m_commandType = DEV_STATUS_REQ; + m_serializedSize = 1; } void -TxParamSetupReq::Serialize (Buffer::Iterator &start) const +TxParamSetupReq::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -TxParamSetupReq::Deserialize (Buffer::Iterator &start) +TxParamSetupReq::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -TxParamSetupReq::Print (std::ostream &os) const +TxParamSetupReq::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "TxParamSetupReq" << std::endl; + os << "TxParamSetupReq" << std::endl; } ////////////////// // TxParamSetupAns // ////////////////// -TxParamSetupAns::TxParamSetupAns () +TxParamSetupAns::TxParamSetupAns() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - m_commandType = DEV_STATUS_REQ; - m_serializedSize = 1; + m_commandType = DEV_STATUS_REQ; + m_serializedSize = 1; } void -TxParamSetupAns::Serialize (Buffer::Iterator &start) const +TxParamSetupAns::Serialize(Buffer::Iterator& start) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Write the CID - start.WriteU8 (GetCIDFromMacCommand (m_commandType)); + // Write the CID + start.WriteU8(GetCIDFromMacCommand(m_commandType)); } uint8_t -TxParamSetupAns::Deserialize (Buffer::Iterator &start) +TxParamSetupAns::Deserialize(Buffer::Iterator& start) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // Consume the CID - start.ReadU8 (); + // Consume the CID + start.ReadU8(); - return m_serializedSize; + return m_serializedSize; } void -TxParamSetupAns::Print (std::ostream &os) const +TxParamSetupAns::Print(std::ostream& os) const { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - os << "TxParamSetupAns" << std::endl; + os << "TxParamSetupAns" << std::endl; } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/mac-command.h b/model/mac-command.h index 05a7700f61..c799fe1c38 100644 --- a/model/mac-command.h +++ b/model/mac-command.h @@ -21,37 +21,39 @@ #ifndef MAC_COMMAND_H #define MAC_COMMAND_H -#include "ns3/object.h" -#include "ns3/nstime.h" #include "ns3/buffer.h" +#include "ns3/nstime.h" +#include "ns3/object.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * Enum for every possible command type */ enum MacCommandType { - INVALID, - LINK_CHECK_REQ, - LINK_CHECK_ANS, - LINK_ADR_REQ, - LINK_ADR_ANS, - DUTY_CYCLE_REQ, - DUTY_CYCLE_ANS, - RX_PARAM_SETUP_REQ, - RX_PARAM_SETUP_ANS, - DEV_STATUS_REQ, - DEV_STATUS_ANS, - NEW_CHANNEL_REQ, - NEW_CHANNEL_ANS, - RX_TIMING_SETUP_REQ, - RX_TIMING_SETUP_ANS, - TX_PARAM_SETUP_REQ, - TX_PARAM_SETUP_ANS, - DL_CHANNEL_REQ, - DL_CHANNEL_ANS + INVALID, + LINK_CHECK_REQ, + LINK_CHECK_ANS, + LINK_ADR_REQ, + LINK_ADR_ANS, + DUTY_CYCLE_REQ, + DUTY_CYCLE_ANS, + RX_PARAM_SETUP_REQ, + RX_PARAM_SETUP_ANS, + DEV_STATUS_REQ, + DEV_STATUS_ANS, + NEW_CHANNEL_REQ, + NEW_CHANNEL_ANS, + RX_TIMING_SETUP_REQ, + RX_TIMING_SETUP_ANS, + TX_PARAM_SETUP_REQ, + TX_PARAM_SETUP_ANS, + DL_CHANNEL_REQ, + DL_CHANNEL_ANS }; /** @@ -63,67 +65,66 @@ enum MacCommandType */ class MacCommand : public Object { -public: - static TypeId GetTypeId (void); - - MacCommand (); - virtual ~MacCommand (); - - /** - * Serialize the contents of this MAC command into a buffer, according to the - * LoRaWAN standard. - * - * \param start A pointer to the buffer into which to serialize the command. - */ - virtual void Serialize (Buffer::Iterator &start) const = 0; - - /** - * Deserialize the buffer into a MAC command. - * - * \param start A pointer to the buffer that contains the serialized command. - * \return the number of bytes that were consumed. - */ - virtual uint8_t Deserialize (Buffer::Iterator &start) = 0; - - /** - * Print the contents of this MAC command in human-readable format. - * - * \param os The std::ostream instance on which to print the MAC command. - */ - virtual void Print (std::ostream &os) const = 0; - - /** - * Get serialized length of this MAC command. - * - * \return The number of bytes the MAC command takes up. - */ - virtual uint8_t GetSerializedSize (void) const; - - /** - * Get the commandType of this MAC command. - * - * \return The type of MAC command this object represents. - */ - virtual enum MacCommandType GetCommandType (void) const; - - /** - * Get the CID that corresponds to this MAC command. - * - * \return The CID as a uint8_t type. - */ - static uint8_t GetCIDFromMacCommand (enum MacCommandType commandType); - -protected: - /** - * The type of this command. - */ - enum MacCommandType m_commandType; - - /** - * This MAC command's serialized size. - */ - uint8_t m_serializedSize; - + public: + static TypeId GetTypeId(void); + + MacCommand(); + virtual ~MacCommand(); + + /** + * Serialize the contents of this MAC command into a buffer, according to the + * LoRaWAN standard. + * + * \param start A pointer to the buffer into which to serialize the command. + */ + virtual void Serialize(Buffer::Iterator& start) const = 0; + + /** + * Deserialize the buffer into a MAC command. + * + * \param start A pointer to the buffer that contains the serialized command. + * \return the number of bytes that were consumed. + */ + virtual uint8_t Deserialize(Buffer::Iterator& start) = 0; + + /** + * Print the contents of this MAC command in human-readable format. + * + * \param os The std::ostream instance on which to print the MAC command. + */ + virtual void Print(std::ostream& os) const = 0; + + /** + * Get serialized length of this MAC command. + * + * \return The number of bytes the MAC command takes up. + */ + virtual uint8_t GetSerializedSize(void) const; + + /** + * Get the commandType of this MAC command. + * + * \return The type of MAC command this object represents. + */ + virtual enum MacCommandType GetCommandType(void) const; + + /** + * Get the CID that corresponds to this MAC command. + * + * \return The CID as a uint8_t type. + */ + static uint8_t GetCIDFromMacCommand(enum MacCommandType commandType); + + protected: + /** + * The type of this command. + */ + enum MacCommandType m_commandType; + + /** + * This MAC command's serialized size. + */ + uint8_t m_serializedSize; }; /** @@ -133,12 +134,12 @@ class MacCommand : public Object */ class LinkCheckReq : public MacCommand { -public: - LinkCheckReq (); - ~LinkCheckReq (); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + public: + LinkCheckReq(); + ~LinkCheckReq(); + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; }; /** @@ -149,57 +150,57 @@ class LinkCheckReq : public MacCommand */ class LinkCheckAns : public MacCommand { -public: - LinkCheckAns (); - LinkCheckAns (uint8_t margin, uint8_t gwCnt); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Set the demodulation margin value. - * - * \param margin The demodulation margin to set. - */ - void SetMargin (uint8_t margin); - - /** - * Get the demodulation margin value. - * - * \return The demodulation margin value. - */ - uint8_t GetMargin (void) const; - - /** - * Set the gateway count value. - * - * \param gwCnt The count value to set. - */ - void SetGwCnt (uint8_t gwCnt); - - /** - * Get the gateway count value. - * - * \return The gateway count value. - */ - uint8_t GetGwCnt (void) const; - - /** - * Increment this MacCommand's gwCnt value. - */ - void IncrementGwCnt (void); - -private: - /** - * This MAC command's demodulation margin value. - */ - uint8_t m_margin; - - /** - * This MAC command's gateway count value. - */ - uint8_t m_gwCnt; + public: + LinkCheckAns(); + LinkCheckAns(uint8_t margin, uint8_t gwCnt); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Set the demodulation margin value. + * + * \param margin The demodulation margin to set. + */ + void SetMargin(uint8_t margin); + + /** + * Get the demodulation margin value. + * + * \return The demodulation margin value. + */ + uint8_t GetMargin(void) const; + + /** + * Set the gateway count value. + * + * \param gwCnt The count value to set. + */ + void SetGwCnt(uint8_t gwCnt); + + /** + * Get the gateway count value. + * + * \return The gateway count value. + */ + uint8_t GetGwCnt(void) const; + + /** + * Increment this MacCommand's gwCnt value. + */ + void IncrementGwCnt(void); + + private: + /** + * This MAC command's demodulation margin value. + */ + uint8_t m_margin; + + /** + * This MAC command's gateway count value. + */ + uint8_t m_gwCnt; }; /** @@ -211,55 +212,58 @@ class LinkCheckAns : public MacCommand */ class LinkAdrReq : public MacCommand { -public: - LinkAdrReq (); - - LinkAdrReq (uint8_t dataRate, uint8_t txPower, uint16_t channelMask, - uint8_t chMaskCntl, uint8_t nbRep); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Return the data rate prescribed by this MAC command. - * - * \return An unsigned 8-bit integer containing the data rate. - */ - uint8_t GetDataRate (void); - - /** - * Get the transmission power prescribed by this MAC command. - * - * The MAC layer is expected to translate this value to a certain power in - * dBm when communicating it to the PHY, and the translation will vary based - * on the region of the device. - * - * \return The TX power, encoded as an unsigned 8-bit integer. - */ - uint8_t GetTxPower (void); - - /** - * Get the list of enabled channels. This method takes the 16-bit channel mask - * and translates it to a list of integers that can be more easily parsed. - * - * \return The list of enabled channels. - */ - std::list GetEnabledChannelsList (void); - - /** - * Get the number of repetitions prescribed by this MAC command. - * - * \return The number of repetitions. - */ - int GetRepetitions (void); - -private: - uint8_t m_dataRate; - uint8_t m_txPower; - uint16_t m_channelMask; - uint8_t m_chMaskCntl; - uint8_t m_nbRep; + public: + LinkAdrReq(); + + LinkAdrReq(uint8_t dataRate, + uint8_t txPower, + uint16_t channelMask, + uint8_t chMaskCntl, + uint8_t nbRep); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Return the data rate prescribed by this MAC command. + * + * \return An unsigned 8-bit integer containing the data rate. + */ + uint8_t GetDataRate(void); + + /** + * Get the transmission power prescribed by this MAC command. + * + * The MAC layer is expected to translate this value to a certain power in + * dBm when communicating it to the PHY, and the translation will vary based + * on the region of the device. + * + * \return The TX power, encoded as an unsigned 8-bit integer. + */ + uint8_t GetTxPower(void); + + /** + * Get the list of enabled channels. This method takes the 16-bit channel mask + * and translates it to a list of integers that can be more easily parsed. + * + * \return The list of enabled channels. + */ + std::list GetEnabledChannelsList(void); + + /** + * Get the number of repetitions prescribed by this MAC command. + * + * \return The number of repetitions. + */ + int GetRepetitions(void); + + private: + uint8_t m_dataRate; + uint8_t m_txPower; + uint16_t m_channelMask; + uint8_t m_chMaskCntl; + uint8_t m_nbRep; }; /** @@ -269,19 +273,19 @@ class LinkAdrReq : public MacCommand */ class LinkAdrAns : public MacCommand { -public: - LinkAdrAns (); + public: + LinkAdrAns(); - LinkAdrAns (bool powerAck, bool dataRateAck, bool channelMaskAck); + LinkAdrAns(bool powerAck, bool dataRateAck, bool channelMaskAck); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; -private: - bool m_powerAck; - bool m_dataRateAck; - bool m_channelMaskAck; + private: + bool m_powerAck; + bool m_dataRateAck; + bool m_channelMaskAck; }; /** @@ -293,28 +297,28 @@ class LinkAdrAns : public MacCommand */ class DutyCycleReq : public MacCommand { -public: - DutyCycleReq (); - /** - * Constructor providing initialization of all parameters. - * - * \param dutyCycle The duty cycle as a 8-bit unsigned integer. - */ - DutyCycleReq (uint8_t dutyCycle); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Get the maximum duty cycle prescribed by this Mac command, in fraction form. - * - * \return The maximum duty cycle. - */ - double GetMaximumAllowedDutyCycle (void) const; - -private: - uint8_t m_maxDCycle; + public: + DutyCycleReq(); + /** + * Constructor providing initialization of all parameters. + * + * \param dutyCycle The duty cycle as a 8-bit unsigned integer. + */ + DutyCycleReq(uint8_t dutyCycle); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Get the maximum duty cycle prescribed by this Mac command, in fraction form. + * + * \return The maximum duty cycle. + */ + double GetMaximumAllowedDutyCycle(void) const; + + private: + uint8_t m_maxDCycle; }; /** @@ -324,12 +328,12 @@ class DutyCycleReq : public MacCommand */ class DutyCycleAns : public MacCommand { -public: - DutyCycleAns (); + public: + DutyCycleAns(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; }; /** @@ -337,47 +341,47 @@ class DutyCycleAns : public MacCommand */ class RxParamSetupReq : public MacCommand { -public: - RxParamSetupReq (); - - /** - * Constructor providing initialization of all fields. - * - * \param rx1DrOffset The Data Rate offset to use for the first receive window. - * \param rx2DataRate The Data Rate to use for the second receive window. - * \param frequency The frequency in Hz to use for the second receive window. - */ - RxParamSetupReq (uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Get this command's Rx1DrOffset parameter. - * - * \return The Rx1DrOffset parameter. - */ - uint8_t GetRx1DrOffset (void); - - /** - * Get this command's Rx2DataRate parameter. - * - * \return The Rx2DataRate parameter. - */ - uint8_t GetRx2DataRate (void); - - /** - * Get this command's frequency. - * - * \return The frequency parameter, in Hz. - */ - double GetFrequency (void); - -private: - uint8_t m_rx1DrOffset; - uint8_t m_rx2DataRate; - double m_frequency; //!< The frequency _in Hz_ + public: + RxParamSetupReq(); + + /** + * Constructor providing initialization of all fields. + * + * \param rx1DrOffset The Data Rate offset to use for the first receive window. + * \param rx2DataRate The Data Rate to use for the second receive window. + * \param frequency The frequency in Hz to use for the second receive window. + */ + RxParamSetupReq(uint8_t rx1DrOffset, uint8_t rx2DataRate, double frequency); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Get this command's Rx1DrOffset parameter. + * + * \return The Rx1DrOffset parameter. + */ + uint8_t GetRx1DrOffset(void); + + /** + * Get this command's Rx2DataRate parameter. + * + * \return The Rx2DataRate parameter. + */ + uint8_t GetRx2DataRate(void); + + /** + * Get this command's frequency. + * + * \return The frequency parameter, in Hz. + */ + double GetFrequency(void); + + private: + uint8_t m_rx1DrOffset; + uint8_t m_rx2DataRate; + double m_frequency; //!< The frequency _in Hz_ }; /** @@ -385,25 +389,25 @@ class RxParamSetupReq : public MacCommand */ class RxParamSetupAns : public MacCommand { -public: - RxParamSetupAns (); - /** - * Constructor with initialization of all parameters. - * - * \param rx1DrOffsetAck Whether or not the offset was correctly set. - * \param rx2DataRateAck Whether or not the second slot data rate was correctly set. - * \param channelAck Whether or not the second slot frequency was correctly set. - */ - RxParamSetupAns (bool rx1DrOffsetAck, bool rx2DataRateAck, bool channelAck); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - -private: - bool m_rx1DrOffsetAck; - bool m_rx2DataRateAck; - bool m_channelAck; + public: + RxParamSetupAns(); + /** + * Constructor with initialization of all parameters. + * + * \param rx1DrOffsetAck Whether or not the offset was correctly set. + * \param rx2DataRateAck Whether or not the second slot data rate was correctly set. + * \param channelAck Whether or not the second slot frequency was correctly set. + */ + RxParamSetupAns(bool rx1DrOffsetAck, bool rx2DataRateAck, bool channelAck); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + private: + bool m_rx1DrOffsetAck; + bool m_rx2DataRateAck; + bool m_channelAck; }; /** @@ -411,12 +415,12 @@ class RxParamSetupAns : public MacCommand */ class DevStatusReq : public MacCommand { -public: - DevStatusReq (); + public: + DevStatusReq(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; }; /** @@ -424,37 +428,37 @@ class DevStatusReq : public MacCommand */ class DevStatusAns : public MacCommand { -public: - DevStatusAns (); - /** - * Constructor with initialization of all parameters. - * - * \param battery The battery level in [0, 255]. - * \param margin The demodulation margin of the last received DevStatusReq packet. - */ - DevStatusAns (uint8_t battery, uint8_t margin); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Get the battery information contained in this MAC command. - * - * \return The battery level. - */ - uint8_t GetBattery (void); - - /** - * Get the demodulation margin contained in this MAC command. - * - * \return The margin. - */ - uint8_t GetMargin (void); - -private: - uint8_t m_battery; - uint8_t m_margin; + public: + DevStatusAns(); + /** + * Constructor with initialization of all parameters. + * + * \param battery The battery level in [0, 255]. + * \param margin The demodulation margin of the last received DevStatusReq packet. + */ + DevStatusAns(uint8_t battery, uint8_t margin); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Get the battery information contained in this MAC command. + * + * \return The battery level. + */ + uint8_t GetBattery(void); + + /** + * Get the demodulation margin contained in this MAC command. + * + * \return The margin. + */ + uint8_t GetMargin(void); + + private: + uint8_t m_battery; + uint8_t m_margin; }; /** @@ -462,33 +466,33 @@ class DevStatusAns : public MacCommand */ class NewChannelReq : public MacCommand { -public: - NewChannelReq (); - - /** - * Constructor providing initialization of all parameters. - * - * \param chIndex The index of the channel this command wants to operate on. - * \param frequency The new frequency for this channel. - * \param minDataRate The minimum data rate allowed on this channel. - * \param maxDataRate The minimum data rate allowed on this channel. - */ - NewChannelReq (uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - uint8_t GetChannelIndex (void); - double GetFrequency (void); - uint8_t GetMinDataRate (void); - uint8_t GetMaxDataRate (void); - -private: - uint8_t m_chIndex; - double m_frequency; - uint8_t m_minDataRate; - uint8_t m_maxDataRate; + public: + NewChannelReq(); + + /** + * Constructor providing initialization of all parameters. + * + * \param chIndex The index of the channel this command wants to operate on. + * \param frequency The new frequency for this channel. + * \param minDataRate The minimum data rate allowed on this channel. + * \param maxDataRate The minimum data rate allowed on this channel. + */ + NewChannelReq(uint8_t chIndex, double frequency, uint8_t minDataRate, uint8_t maxDataRate); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + uint8_t GetChannelIndex(void); + double GetFrequency(void); + uint8_t GetMinDataRate(void); + uint8_t GetMaxDataRate(void); + + private: + uint8_t m_chIndex; + double m_frequency; + uint8_t m_minDataRate; + uint8_t m_maxDataRate; }; /** @@ -496,26 +500,26 @@ class NewChannelReq : public MacCommand */ class NewChannelAns : public MacCommand { -public: - NewChannelAns (); - - /** - * Constructor providing initialization of all parameters. - * - * \param dataRateRangeOk Whether or not the requested data rate range was set - * correctly. - * \param channelFrequencyOk Whether or not the requested channel frequency - * was set correctly. - */ - NewChannelAns (bool dataRateRangeOk, bool channelFrequencyOk); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - -private: - bool m_dataRateRangeOk; - bool m_channelFrequencyOk; + public: + NewChannelAns(); + + /** + * Constructor providing initialization of all parameters. + * + * \param dataRateRangeOk Whether or not the requested data rate range was set + * correctly. + * \param channelFrequencyOk Whether or not the requested channel frequency + * was set correctly. + */ + NewChannelAns(bool dataRateRangeOk, bool channelFrequencyOk); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + private: + bool m_dataRateRangeOk; + bool m_channelFrequencyOk; }; /** @@ -523,29 +527,29 @@ class NewChannelAns : public MacCommand */ class RxTimingSetupReq : public MacCommand { -public: - RxTimingSetupReq (); - - /** - * Constructor providing initialization of all parameters. - * - * \param delay The delay encoded in this MAC command. - */ - RxTimingSetupReq (uint8_t delay); - - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; - - /** - * Get the first window delay as a Time instance. - * - * \return The delay. - */ - Time GetDelay (void); - -private: - uint8_t m_delay; + public: + RxTimingSetupReq(); + + /** + * Constructor providing initialization of all parameters. + * + * \param delay The delay encoded in this MAC command. + */ + RxTimingSetupReq(uint8_t delay); + + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; + + /** + * Get the first window delay as a Time instance. + * + * \return The delay. + */ + Time GetDelay(void); + + private: + uint8_t m_delay; }; /** @@ -555,14 +559,14 @@ class RxTimingSetupReq : public MacCommand */ class RxTimingSetupAns : public MacCommand { -public: - RxTimingSetupAns (); + public: + RxTimingSetupAns(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; -private: + private: }; /** @@ -570,14 +574,14 @@ class RxTimingSetupAns : public MacCommand */ class TxParamSetupAns : public MacCommand { -public: - TxParamSetupAns (); + public: + TxParamSetupAns(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; -private: + private: }; /** @@ -585,14 +589,14 @@ class TxParamSetupAns : public MacCommand */ class TxParamSetupReq : public MacCommand { -public: - TxParamSetupReq (); + public: + TxParamSetupReq(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; -private: + private: }; /** @@ -600,16 +604,16 @@ class TxParamSetupReq : public MacCommand */ class DlChannelAns : public MacCommand { -public: - DlChannelAns (); + public: + DlChannelAns(); - virtual void Serialize (Buffer::Iterator &start) const; - virtual uint8_t Deserialize (Buffer::Iterator &start); - virtual void Print (std::ostream &os) const; + virtual void Serialize(Buffer::Iterator& start) const; + virtual uint8_t Deserialize(Buffer::Iterator& start); + virtual void Print(std::ostream& os) const; -private: + private: }; -} +} // namespace lorawan -} +} // namespace ns3 #endif /* DEVICE_STATUS_H */ diff --git a/model/network-controller-components.cc b/model/network-controller-components.cc index 0aa5a51192..f395983804 100644 --- a/model/network-controller-components.cc +++ b/model/network-controller-components.cc @@ -18,30 +18,31 @@ * Author: Davide Magrin */ -#include "ns3/network-controller-components.h" +#include "network-controller-components.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkControllerComponent"); +NS_LOG_COMPONENT_DEFINE("NetworkControllerComponent"); -NS_OBJECT_ENSURE_REGISTERED (NetworkControllerComponent); +NS_OBJECT_ENSURE_REGISTERED(NetworkControllerComponent); TypeId -NetworkControllerComponent::GetTypeId (void) +NetworkControllerComponent::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::NetworkControllerComponent") - .SetParent () - .SetGroupName ("lorawan") - ; - return tid; + static TypeId tid = + TypeId("ns3::NetworkControllerComponent").SetParent().SetGroupName("lorawan"); + return tid; } // Constructor and destructor -NetworkControllerComponent::NetworkControllerComponent () +NetworkControllerComponent::NetworkControllerComponent() { } -NetworkControllerComponent::~NetworkControllerComponent () + +NetworkControllerComponent::~NetworkControllerComponent() { } @@ -49,151 +50,152 @@ NetworkControllerComponent::~NetworkControllerComponent () // ConfirmedMessagesComponent // //////////////////////////////// TypeId -ConfirmedMessagesComponent::GetTypeId (void) +ConfirmedMessagesComponent::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::ConfirmedMessagesComponent") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::ConfirmedMessagesComponent") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -ConfirmedMessagesComponent::ConfirmedMessagesComponent () +ConfirmedMessagesComponent::ConfirmedMessagesComponent() { } -ConfirmedMessagesComponent::~ConfirmedMessagesComponent () + +ConfirmedMessagesComponent::~ConfirmedMessagesComponent() { } void -ConfirmedMessagesComponent::OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus) +ConfirmedMessagesComponent::OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this->GetTypeId () << packet << networkStatus); + NS_LOG_FUNCTION(this->GetTypeId() << packet << networkStatus); - // Check whether the received packet requires an acknowledgment. - LorawanMacHeader mHdr; - LoraFrameHeader fHdr; - fHdr.SetAsUplink (); - Ptr myPacket = packet->Copy (); - myPacket->RemoveHeader (mHdr); - myPacket->RemoveHeader (fHdr); + // Check whether the received packet requires an acknowledgment. + LorawanMacHeader mHdr; + LoraFrameHeader fHdr; + fHdr.SetAsUplink(); + Ptr myPacket = packet->Copy(); + myPacket->RemoveHeader(mHdr); + myPacket->RemoveHeader(fHdr); - NS_LOG_INFO ("Received packet Mac Header: " << mHdr); - NS_LOG_INFO ("Received packet Frame Header: " << fHdr); + NS_LOG_INFO("Received packet Mac Header: " << mHdr); + NS_LOG_INFO("Received packet Frame Header: " << fHdr); - if (mHdr.GetMType () == LorawanMacHeader::CONFIRMED_DATA_UP) + if (mHdr.GetMType() == LorawanMacHeader::CONFIRMED_DATA_UP) { - NS_LOG_INFO ("Packet requires confirmation"); - - // Set up the ACK bit on the reply - status->m_reply.frameHeader.SetAsDownlink (); - status->m_reply.frameHeader.SetAck (true); - status->m_reply.frameHeader.SetAddress (fHdr.GetAddress ()); - status->m_reply.macHeader.SetMType (LorawanMacHeader::UNCONFIRMED_DATA_DOWN); - status->m_reply.needsReply = true; - - // Note that the acknowledgment procedure dies here: "Acknowledgments - // are only snt in response to the latest message received and are never - // retransmitted". We interpret this to mean that only the current - // reception window can be used, and that the Ack field should be - // emptied in case transmission cannot be performed in the current - // window. Because of this, in this component's OnFailedReply method we - // void the ack bits. + NS_LOG_INFO("Packet requires confirmation"); + + // Set up the ACK bit on the reply + status->m_reply.frameHeader.SetAsDownlink(); + status->m_reply.frameHeader.SetAck(true); + status->m_reply.frameHeader.SetAddress(fHdr.GetAddress()); + status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN); + status->m_reply.needsReply = true; + + // Note that the acknowledgment procedure dies here: "Acknowledgments + // are only snt in response to the latest message received and are never + // retransmitted". We interpret this to mean that only the current + // reception window can be used, and that the Ack field should be + // emptied in case transmission cannot be performed in the current + // window. Because of this, in this component's OnFailedReply method we + // void the ack bits. } } void -ConfirmedMessagesComponent::BeforeSendingReply (Ptr status, - Ptr networkStatus) +ConfirmedMessagesComponent::BeforeSendingReply(Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this << status << networkStatus); - // Nothing to do in this case + NS_LOG_FUNCTION(this << status << networkStatus); + // Nothing to do in this case } void -ConfirmedMessagesComponent::OnFailedReply (Ptr status, - Ptr networkStatus) +ConfirmedMessagesComponent::OnFailedReply(Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this << networkStatus); + NS_LOG_FUNCTION(this << networkStatus); - // Empty the Ack bit. - status->m_reply.frameHeader.SetAck (false); + // Empty the Ack bit. + status->m_reply.frameHeader.SetAck(false); } //////////////////////// // LinkCheckComponent // //////////////////////// TypeId -LinkCheckComponent::GetTypeId (void) +LinkCheckComponent::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::LinkCheckComponent") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::LinkCheckComponent") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -LinkCheckComponent::LinkCheckComponent () +LinkCheckComponent::LinkCheckComponent() { } -LinkCheckComponent::~LinkCheckComponent () + +LinkCheckComponent::~LinkCheckComponent() { } void -LinkCheckComponent::OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus) +LinkCheckComponent::OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this->GetTypeId () << packet << networkStatus); + NS_LOG_FUNCTION(this->GetTypeId() << packet << networkStatus); - // We will only act just before reply, when all Gateways will have received - // the packet. + // We will only act just before reply, when all Gateways will have received + // the packet. } void -LinkCheckComponent::BeforeSendingReply (Ptr status, - Ptr networkStatus) +LinkCheckComponent::BeforeSendingReply(Ptr status, + Ptr networkStatus) { - NS_LOG_FUNCTION (this << status << networkStatus); + NS_LOG_FUNCTION(this << status << networkStatus); - Ptr myPacket = status->GetLastPacketReceivedFromDevice ()->Copy (); - LorawanMacHeader mHdr; - LoraFrameHeader fHdr; - fHdr.SetAsUplink (); - myPacket->RemoveHeader (mHdr); - myPacket->RemoveHeader (fHdr); + Ptr myPacket = status->GetLastPacketReceivedFromDevice()->Copy(); + LorawanMacHeader mHdr; + LoraFrameHeader fHdr; + fHdr.SetAsUplink(); + myPacket->RemoveHeader(mHdr); + myPacket->RemoveHeader(fHdr); - Ptr command = fHdr.GetMacCommand (); + Ptr command = fHdr.GetMacCommand(); - // GetMacCommand returns 0 if no command is found - if (command) + // GetMacCommand returns 0 if no command is found + if (command) { - status->m_reply.needsReply = true; + status->m_reply.needsReply = true; - // Get the number of gateways that received the packet and the best - // margin - uint8_t gwCount = status->GetLastReceivedPacketInfo ().gwList.size (); + // Get the number of gateways that received the packet and the best + // margin + uint8_t gwCount = status->GetLastReceivedPacketInfo().gwList.size(); - Ptr replyCommand = Create (); - replyCommand->SetGwCnt (gwCount); - status->m_reply.frameHeader.SetAsDownlink (); - status->m_reply.frameHeader.AddCommand (replyCommand); - status->m_reply.macHeader.SetMType (LorawanMacHeader::UNCONFIRMED_DATA_DOWN); + Ptr replyCommand = Create(); + replyCommand->SetGwCnt(gwCount); + status->m_reply.frameHeader.SetAsDownlink(); + status->m_reply.frameHeader.AddCommand(replyCommand); + status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN); } - else + else { - // Do nothing + // Do nothing } } void -LinkCheckComponent::OnFailedReply (Ptr status, - Ptr networkStatus) +LinkCheckComponent::OnFailedReply(Ptr status, Ptr networkStatus) { - NS_LOG_FUNCTION (this->GetTypeId () << networkStatus); -} -} + NS_LOG_FUNCTION(this->GetTypeId() << networkStatus); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/network-controller-components.h b/model/network-controller-components.h index 30222280b6..759fc72d5e 100644 --- a/model/network-controller-components.h +++ b/model/network-controller-components.h @@ -21,13 +21,16 @@ #ifndef NETWORK_CONTROLLER_COMPONENTS_H #define NETWORK_CONTROLLER_COMPONENTS_H -#include "ns3/object.h" +#include "network-status.h" + #include "ns3/log.h" +#include "ns3/object.h" #include "ns3/packet.h" -#include "ns3/network-status.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class NetworkStatus; @@ -44,36 +47,35 @@ class NetworkStatus; */ class NetworkControllerComponent : public Object { -public: - static TypeId GetTypeId (void); - - // Constructor and destructor - NetworkControllerComponent (); - virtual ~NetworkControllerComponent (); - - // Virtual methods whose implementation is left to child classes - /** - * Method that is called when a new packet is received by the NetworkServer. - * - * \param packet The newly received packet - * \param networkStatus A pointer to the NetworkStatus object - */ - virtual void OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus) = 0; - - virtual void BeforeSendingReply (Ptr status, - Ptr networkStatus) = 0; - - /** - * Method that is called when a packet cannot be sent in the downlink. - * - * \param status The EndDeviceStatus of the device to which it was - * impossible to send a reply. - * \param networkStatus A pointer to the NetworkStatus object - */ - virtual void OnFailedReply (Ptr status, - Ptr networkStatus) = 0; + public: + static TypeId GetTypeId(void); + + // Constructor and destructor + NetworkControllerComponent(); + virtual ~NetworkControllerComponent(); + + // Virtual methods whose implementation is left to child classes + /** + * Method that is called when a new packet is received by the NetworkServer. + * + * \param packet The newly received packet + * \param networkStatus A pointer to the NetworkStatus object + */ + virtual void OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus) = 0; + + virtual void BeforeSendingReply(Ptr status, + Ptr networkStatus) = 0; + + /** + * Method that is called when a packet cannot be sent in the downlink. + * + * \param status The EndDeviceStatus of the device to which it was + * impossible to send a reply. + * \param networkStatus A pointer to the NetworkStatus object + */ + virtual void OnFailedReply(Ptr status, Ptr networkStatus) = 0; }; /////////////////////////////// @@ -82,29 +84,27 @@ class NetworkControllerComponent : public Object class ConfirmedMessagesComponent : public NetworkControllerComponent { -public: - static TypeId GetTypeId (void); - - // Constructor and destructor - ConfirmedMessagesComponent (); - virtual ~ConfirmedMessagesComponent (); - - /** - * This method checks whether the received packet requires an acknowledgment - * and sets up the appropriate reply in case it does. - * - * \param packet The newly received packet - * \param networkStatus A pointer to the NetworkStatus object - */ - void OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus); - - void BeforeSendingReply (Ptr status, - Ptr networkStatus); - - void OnFailedReply (Ptr status, - Ptr networkStatus); + public: + static TypeId GetTypeId(void); + + // Constructor and destructor + ConfirmedMessagesComponent(); + virtual ~ConfirmedMessagesComponent(); + + /** + * This method checks whether the received packet requires an acknowledgment + * and sets up the appropriate reply in case it does. + * + * \param packet The newly received packet + * \param networkStatus A pointer to the NetworkStatus object + */ + void OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus); + + void BeforeSendingReply(Ptr status, Ptr networkStatus); + + void OnFailedReply(Ptr status, Ptr networkStatus); }; /////////////////////////////////// @@ -113,35 +113,32 @@ class ConfirmedMessagesComponent : public NetworkControllerComponent class LinkCheckComponent : public NetworkControllerComponent { -public: - static TypeId GetTypeId (void); - - // Constructor and destructor - LinkCheckComponent (); - virtual ~LinkCheckComponent (); - - /** - * This method checks whether the received packet requires an acknowledgment - * and sets up the appropriate reply in case it does. - * - * \param packet The newly received packet - * \param networkStatus A pointer to the NetworkStatus object - */ - void OnReceivedPacket (Ptr packet, - Ptr status, - Ptr networkStatus); - - void BeforeSendingReply (Ptr status, - Ptr networkStatus); - - void OnFailedReply (Ptr status, - Ptr networkStatus); - -private: - void UpdateLinkCheckAns (Ptr packet, - Ptr status); + public: + static TypeId GetTypeId(void); + + // Constructor and destructor + LinkCheckComponent(); + virtual ~LinkCheckComponent(); + + /** + * This method checks whether the received packet requires an acknowledgment + * and sets up the appropriate reply in case it does. + * + * \param packet The newly received packet + * \param networkStatus A pointer to the NetworkStatus object + */ + void OnReceivedPacket(Ptr packet, + Ptr status, + Ptr networkStatus); + + void BeforeSendingReply(Ptr status, Ptr networkStatus); + + void OnFailedReply(Ptr status, Ptr networkStatus); + + private: + void UpdateLinkCheckAns(Ptr packet, Ptr status); }; -} +} // namespace lorawan -} +} // namespace ns3 #endif diff --git a/model/network-controller.cc b/model/network-controller.cc index e66c625257..8ee6111ba4 100644 --- a/model/network-controller.cc +++ b/model/network-controller.cc @@ -20,74 +20,74 @@ #include "network-controller.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkController"); +NS_LOG_COMPONENT_DEFINE("NetworkController"); -NS_OBJECT_ENSURE_REGISTERED (NetworkController); +NS_OBJECT_ENSURE_REGISTERED(NetworkController); TypeId -NetworkController::GetTypeId (void) +NetworkController::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::NetworkController") - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::NetworkController") + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -NetworkController::NetworkController () +NetworkController::NetworkController() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -NetworkController::NetworkController (Ptr networkStatus) : - m_status (networkStatus) +NetworkController::NetworkController(Ptr networkStatus) + : m_status(networkStatus) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -NetworkController::~NetworkController () +NetworkController::~NetworkController() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -NetworkController::Install (Ptr component) +NetworkController::Install(Ptr component) { - NS_LOG_FUNCTION (this); - m_components.push_back (component); + NS_LOG_FUNCTION(this); + m_components.push_back(component); } void -NetworkController::OnNewPacket (Ptr packet) +NetworkController::OnNewPacket(Ptr packet) { - NS_LOG_FUNCTION (this << packet); + NS_LOG_FUNCTION(this << packet); - // NOTE As a future optimization, we can allow components to register their - // callbacks and only be called in case a certain MAC command is contained. - // For now, we call all components. + // NOTE As a future optimization, we can allow components to register their + // callbacks and only be called in case a certain MAC command is contained. + // For now, we call all components. - // Inform each component about the new packet - for (auto it = m_components.begin (); it != m_components.end (); ++it) + // Inform each component about the new packet + for (auto it = m_components.begin(); it != m_components.end(); ++it) { - (*it)->OnReceivedPacket (packet, - m_status->GetEndDeviceStatus (packet), - m_status); + (*it)->OnReceivedPacket(packet, m_status->GetEndDeviceStatus(packet), m_status); } } void -NetworkController::BeforeSendingReply (Ptr endDeviceStatus) +NetworkController::BeforeSendingReply(Ptr endDeviceStatus) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Inform each component about the imminent reply - for (auto it = m_components.begin (); it != m_components.end (); ++it) + // Inform each component about the imminent reply + for (auto it = m_components.begin(); it != m_components.end(); ++it) { - (*it)->BeforeSendingReply (endDeviceStatus, m_status); + (*it)->BeforeSendingReply(endDeviceStatus, m_status); } } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/network-controller.h b/model/network-controller.h index 7e7ee3e9ab..f1ad5e8f13 100644 --- a/model/network-controller.h +++ b/model/network-controller.h @@ -21,13 +21,16 @@ #ifndef NETWORK_CONTROLLER_H #define NETWORK_CONTROLLER_H +#include "network-controller-components.h" +#include "network-status.h" + #include "ns3/object.h" #include "ns3/packet.h" -#include "ns3/network-status.h" -#include "ns3/network-controller-components.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class NetworkStatus; class NetworkControllerComponent; @@ -39,37 +42,37 @@ class NetworkControllerComponent; */ class NetworkController : public Object { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); - NetworkController (); - NetworkController (Ptr networkStatus); - virtual ~NetworkController (); + NetworkController(); + NetworkController(Ptr networkStatus); + virtual ~NetworkController(); - /** - * Add a new NetworkControllerComponent - */ - void Install (Ptr component); + /** + * Add a new NetworkControllerComponent + */ + void Install(Ptr component); - /** - * Method that is called by the NetworkServer when a new packet is received. - * - * \param packet The newly received packet. - */ - void OnNewPacket (Ptr packet); + /** + * Method that is called by the NetworkServer when a new packet is received. + * + * \param packet The newly received packet. + */ + void OnNewPacket(Ptr packet); - /** - * Method that is called by the NetworkScheduler just before sending a reply - * to a certain End Device. - */ - void BeforeSendingReply (Ptr endDeviceStatus); + /** + * Method that is called by the NetworkScheduler just before sending a reply + * to a certain End Device. + */ + void BeforeSendingReply(Ptr endDeviceStatus); -private: - Ptr m_status; - std::list > m_components; + private: + Ptr m_status; + std::list> m_components; }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* NETWORK_CONTROLLER_H */ diff --git a/model/network-scheduler.cc b/model/network-scheduler.cc index afbaa21e19..c4515064b3 100644 --- a/model/network-scheduler.cc +++ b/model/network-scheduler.cc @@ -1,134 +1,134 @@ #include "network-scheduler.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkScheduler"); +NS_LOG_COMPONENT_DEFINE("NetworkScheduler"); -NS_OBJECT_ENSURE_REGISTERED (NetworkScheduler); +NS_OBJECT_ENSURE_REGISTERED(NetworkScheduler); TypeId -NetworkScheduler::GetTypeId (void) +NetworkScheduler::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::NetworkScheduler") - .SetParent () - .AddConstructor () - .AddTraceSource ("ReceiveWindowOpened", - "Trace source that is fired when a receive window opportunity happens.", - MakeTraceSourceAccessor (&NetworkScheduler::m_receiveWindowOpened), - "ns3::Packet::TracedCallback") - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::NetworkScheduler") + .SetParent() + .AddConstructor() + .AddTraceSource("ReceiveWindowOpened", + "Trace source that is fired when a receive window opportunity happens.", + MakeTraceSourceAccessor(&NetworkScheduler::m_receiveWindowOpened), + "ns3::Packet::TracedCallback") + .SetGroupName("lorawan"); + return tid; } -NetworkScheduler::NetworkScheduler () +NetworkScheduler::NetworkScheduler() { } -NetworkScheduler::NetworkScheduler (Ptr status, - Ptr controller) : - m_status (status), - m_controller (controller) +NetworkScheduler::NetworkScheduler(Ptr status, Ptr controller) + : m_status(status), + m_controller(controller) { } -NetworkScheduler::~NetworkScheduler () +NetworkScheduler::~NetworkScheduler() { } void -NetworkScheduler::OnReceivedPacket (Ptr packet) +NetworkScheduler::OnReceivedPacket(Ptr packet) { - NS_LOG_FUNCTION (packet); - - // Get the current packet's frame counter - Ptr packetCopy = packet->Copy (); - LorawanMacHeader receivedMacHdr; - packetCopy->RemoveHeader (receivedMacHdr); - LoraFrameHeader receivedFrameHdr; - receivedFrameHdr.SetAsUplink (); - packetCopy->RemoveHeader (receivedFrameHdr); - - // Need to decide whether to schedule a receive window - if (!m_status->GetEndDeviceStatus (packet)->HasReceiveWindowOpportunityScheduled ()) - { - // Extract the address - LoraDeviceAddress deviceAddress = receivedFrameHdr.GetAddress (); - - // Schedule OnReceiveWindowOpportunity event - m_status->GetEndDeviceStatus (packet)->SetReceiveWindowOpportunity ( - Simulator::Schedule (Seconds (1), - &NetworkScheduler::OnReceiveWindowOpportunity, - this, - deviceAddress, - 1)); // This will be the first receive window - } + NS_LOG_FUNCTION(packet); + + // Get the current packet's frame counter + Ptr packetCopy = packet->Copy(); + LorawanMacHeader receivedMacHdr; + packetCopy->RemoveHeader(receivedMacHdr); + LoraFrameHeader receivedFrameHdr; + receivedFrameHdr.SetAsUplink(); + packetCopy->RemoveHeader(receivedFrameHdr); + + // Need to decide whether to schedule a receive window + if (!m_status->GetEndDeviceStatus(packet)->HasReceiveWindowOpportunityScheduled()) + { + // Extract the address + LoraDeviceAddress deviceAddress = receivedFrameHdr.GetAddress(); + + // Schedule OnReceiveWindowOpportunity event + m_status->GetEndDeviceStatus(packet)->SetReceiveWindowOpportunity( + Simulator::Schedule(Seconds(1), + &NetworkScheduler::OnReceiveWindowOpportunity, + this, + deviceAddress, + 1)); // This will be the first receive window + } } void -NetworkScheduler::OnReceiveWindowOpportunity (LoraDeviceAddress deviceAddress, int window) +NetworkScheduler::OnReceiveWindowOpportunity(LoraDeviceAddress deviceAddress, int window) { - NS_LOG_FUNCTION (deviceAddress); + NS_LOG_FUNCTION(deviceAddress); - NS_LOG_DEBUG ("Opening receive window number " << window << " for device " - << deviceAddress); + NS_LOG_DEBUG("Opening receive window number " << window << " for device " << deviceAddress); - // Check whether we can send a reply to the device, again by using - // NetworkStatus - Address gwAddress = m_status->GetBestGatewayForDevice (deviceAddress, window); + // Check whether we can send a reply to the device, again by using + // NetworkStatus + Address gwAddress = m_status->GetBestGatewayForDevice(deviceAddress, window); - if (gwAddress == Address () && window == 1) + if (gwAddress == Address() && window == 1) { - NS_LOG_DEBUG ("No suitable gateway found for first window."); - - // No suitable GW was found, but there's still hope to find one for the - // second window. - // Schedule another OnReceiveWindowOpportunity event - m_status->GetEndDeviceStatus (deviceAddress)->SetReceiveWindowOpportunity ( - Simulator::Schedule (Seconds (1), - &NetworkScheduler::OnReceiveWindowOpportunity, - this, - deviceAddress, - 2)); // This will be the second receive window + NS_LOG_DEBUG("No suitable gateway found for first window."); + + // No suitable GW was found, but there's still hope to find one for the + // second window. + // Schedule another OnReceiveWindowOpportunity event + m_status->GetEndDeviceStatus(deviceAddress) + ->SetReceiveWindowOpportunity( + Simulator::Schedule(Seconds(1), + &NetworkScheduler::OnReceiveWindowOpportunity, + this, + deviceAddress, + 2)); // This will be the second receive window } - else if (gwAddress == Address () && window == 2) + else if (gwAddress == Address() && window == 2) { - // No suitable GW was found and this was our last opportunity - // Simply give up. - NS_LOG_DEBUG ("Giving up on reply: no suitable gateway was found " << - "on the second receive window"); - - // Reset the reply - // XXX Should we reset it here or keep it for the next opportunity? - m_status->GetEndDeviceStatus (deviceAddress)->RemoveReceiveWindowOpportunity(); - m_status->GetEndDeviceStatus (deviceAddress)->InitializeReply (); + // No suitable GW was found and this was our last opportunity + // Simply give up. + NS_LOG_DEBUG("Giving up on reply: no suitable gateway was found " + << "on the second receive window"); + + // Reset the reply + // XXX Should we reset it here or keep it for the next opportunity? + m_status->GetEndDeviceStatus(deviceAddress)->RemoveReceiveWindowOpportunity(); + m_status->GetEndDeviceStatus(deviceAddress)->InitializeReply(); } - else + else { - // A gateway was found + // A gateway was found - NS_LOG_DEBUG ("Found available gateway with address: " << gwAddress); + NS_LOG_DEBUG("Found available gateway with address: " << gwAddress); - m_controller->BeforeSendingReply (m_status->GetEndDeviceStatus - (deviceAddress)); + m_controller->BeforeSendingReply(m_status->GetEndDeviceStatus(deviceAddress)); - // Check whether this device needs a response by querying m_status - bool needsReply = m_status->NeedsReply (deviceAddress); + // Check whether this device needs a response by querying m_status + bool needsReply = m_status->NeedsReply(deviceAddress); - if (needsReply) + if (needsReply) { - NS_LOG_INFO ("A reply is needed"); + NS_LOG_INFO("A reply is needed"); - // Send the reply through that gateway - m_status->SendThroughGateway (m_status->GetReplyForDevice - (deviceAddress, window), - gwAddress); + // Send the reply through that gateway + m_status->SendThroughGateway(m_status->GetReplyForDevice(deviceAddress, window), + gwAddress); - // Reset the reply - m_status->GetEndDeviceStatus (deviceAddress)->RemoveReceiveWindowOpportunity(); - m_status->GetEndDeviceStatus (deviceAddress)->InitializeReply (); + // Reset the reply + m_status->GetEndDeviceStatus(deviceAddress)->RemoveReceiveWindowOpportunity(); + m_status->GetEndDeviceStatus(deviceAddress)->InitializeReply(); } } } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/network-scheduler.h b/model/network-scheduler.h index e7024f3174..96a7893d33 100644 --- a/model/network-scheduler.h +++ b/model/network-scheduler.h @@ -21,51 +21,53 @@ #ifndef NETWORK_SCHEDULER_H #define NETWORK_SCHEDULER_H +#include "lora-device-address.h" +#include "lora-frame-header.h" +#include "lorawan-mac-header.h" +#include "network-controller.h" +#include "network-status.h" + +#include "ns3/core-module.h" #include "ns3/object.h" #include "ns3/packet.h" -#include "ns3/core-module.h" -#include "ns3/lora-device-address.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/lora-frame-header.h" -#include "ns3/network-controller.h" -#include "ns3/network-status.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class NetworkStatus; // Forward declaration -class NetworkController; // Forward declaration +class NetworkController; // Forward declaration class NetworkScheduler : public Object { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); - NetworkScheduler (); - NetworkScheduler (Ptr status, - Ptr controller); - virtual ~NetworkScheduler (); + NetworkScheduler(); + NetworkScheduler(Ptr status, Ptr controller); + virtual ~NetworkScheduler(); - /** - * Method called by NetworkServer to inform the Scheduler of a newly arrived - * uplink packet. This function schedules the OnReceiveWindowOpportunity - * events 1 and 2 seconds later. - */ - void OnReceivedPacket (Ptr packet); + /** + * Method called by NetworkServer to inform the Scheduler of a newly arrived + * uplink packet. This function schedules the OnReceiveWindowOpportunity + * events 1 and 2 seconds later. + */ + void OnReceivedPacket(Ptr packet); - /** - * Method that is scheduled after packet arrivals in order to act on - * receive windows 1 and 2 seconds later receptions. - */ - void OnReceiveWindowOpportunity (LoraDeviceAddress deviceAddress, int window); + /** + * Method that is scheduled after packet arrivals in order to act on + * receive windows 1 and 2 seconds later receptions. + */ + void OnReceiveWindowOpportunity(LoraDeviceAddress deviceAddress, int window); -private: - TracedCallback > m_receiveWindowOpened; - Ptr m_status; - Ptr m_controller; + private: + TracedCallback> m_receiveWindowOpened; + Ptr m_status; + Ptr m_controller; }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* NETWORK_SCHEDULER_H */ diff --git a/model/network-server.cc b/model/network-server.cc index a51b7184a4..e5d75b7712 100644 --- a/model/network-server.cc +++ b/model/network-server.cc @@ -19,173 +19,178 @@ * Martina Capuzzo */ -#include "ns3/network-server.h" +#include "network-server.h" + +#include "class-a-end-device-lorawan-mac.h" +#include "lora-device-address.h" +#include "lora-frame-header.h" +#include "lorawan-mac-header.h" +#include "mac-command.h" +#include "network-status.h" + #include "ns3/net-device.h" -#include "ns3/point-to-point-net-device.h" -#include "ns3/packet.h" -#include "ns3/lorawan-mac-header.h" -#include "ns3/lora-frame-header.h" -#include "ns3/lora-device-address.h" -#include "ns3/network-status.h" -#include "ns3/lora-frame-header.h" #include "ns3/node-container.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/mac-command.h" +#include "ns3/packet.h" +#include "ns3/point-to-point-net-device.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkServer"); +NS_LOG_COMPONENT_DEFINE("NetworkServer"); -NS_OBJECT_ENSURE_REGISTERED (NetworkServer); +NS_OBJECT_ENSURE_REGISTERED(NetworkServer); TypeId -NetworkServer::GetTypeId (void) +NetworkServer::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::NetworkServer") - .SetParent () - .AddConstructor () - .AddTraceSource ("ReceivedPacket", - "Trace source that is fired when a packet arrives at the Network Server", - MakeTraceSourceAccessor (&NetworkServer::m_receivedPacket), - "ns3::Packet::TracedCallback") - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::NetworkServer") + .SetParent() + .AddConstructor() + .AddTraceSource( + "ReceivedPacket", + "Trace source that is fired when a packet arrives at the Network Server", + MakeTraceSourceAccessor(&NetworkServer::m_receivedPacket), + "ns3::Packet::TracedCallback") + .SetGroupName("lorawan"); + return tid; } -NetworkServer::NetworkServer () : - m_status (Create ()), - m_controller (Create (m_status)), - m_scheduler (Create (m_status, m_controller)) +NetworkServer::NetworkServer() + : m_status(Create()), + m_controller(Create(m_status)), + m_scheduler(Create(m_status, m_controller)) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -NetworkServer::~NetworkServer () +NetworkServer::~NetworkServer() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -NetworkServer::StartApplication (void) +NetworkServer::StartApplication(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -NetworkServer::StopApplication (void) +NetworkServer::StopApplication(void) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -NetworkServer::AddGateway (Ptr gateway, Ptr netDevice) +NetworkServer::AddGateway(Ptr gateway, Ptr netDevice) { - NS_LOG_FUNCTION (this << gateway); + NS_LOG_FUNCTION(this << gateway); - // Get the PointToPointNetDevice - Ptr p2pNetDevice; - for (uint32_t i = 0; i < gateway->GetNDevices (); i++) + // Get the PointToPointNetDevice + Ptr p2pNetDevice; + for (uint32_t i = 0; i < gateway->GetNDevices(); i++) { - p2pNetDevice = gateway->GetDevice (i)->GetObject (); - if (p2pNetDevice) + p2pNetDevice = gateway->GetDevice(i)->GetObject(); + if (p2pNetDevice) { - // We found a p2pNetDevice on the gateway - break; + // We found a p2pNetDevice on the gateway + break; } } - // Get the gateway's LoRa MAC layer (assumes gateway's MAC is configured as first device) - Ptr gwMac = gateway->GetDevice (0)->GetObject ()-> - GetMac ()->GetObject (); - NS_ASSERT (gwMac); + // Get the gateway's LoRa MAC layer (assumes gateway's MAC is configured as first device) + Ptr gwMac = + gateway->GetDevice(0)->GetObject()->GetMac()->GetObject(); + NS_ASSERT(gwMac); - // Get the Address - Address gatewayAddress = p2pNetDevice->GetAddress (); + // Get the Address + Address gatewayAddress = p2pNetDevice->GetAddress(); - // Create new gatewayStatus - Ptr gwStatus = Create (gatewayAddress, - netDevice, - gwMac); + // Create new gatewayStatus + Ptr gwStatus = Create(gatewayAddress, netDevice, gwMac); - m_status->AddGateway (gatewayAddress, gwStatus); + m_status->AddGateway(gatewayAddress, gwStatus); } void -NetworkServer::AddNodes (NodeContainer nodes) +NetworkServer::AddNodes(NodeContainer nodes) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); - // For each node in the container, call the function to add that single node - NodeContainer::Iterator it; - for (it = nodes.Begin (); it != nodes.End (); it++) + // For each node in the container, call the function to add that single node + NodeContainer::Iterator it; + for (it = nodes.Begin(); it != nodes.End(); it++) { - AddNode (*it); + AddNode(*it); } } void -NetworkServer::AddNode (Ptr node) +NetworkServer::AddNode(Ptr node) { - NS_LOG_FUNCTION (this << node); + NS_LOG_FUNCTION(this << node); - // Get the LoraNetDevice - Ptr loraNetDevice; - for (uint32_t i = 0; i < node->GetNDevices (); i++) + // Get the LoraNetDevice + Ptr loraNetDevice; + for (uint32_t i = 0; i < node->GetNDevices(); i++) { - loraNetDevice = node->GetDevice (i)->GetObject (); - if (loraNetDevice) + loraNetDevice = node->GetDevice(i)->GetObject(); + if (loraNetDevice) { - // We found a LoraNetDevice on the node - break; + // We found a LoraNetDevice on the node + break; } } - // Get the MAC - Ptr edLorawanMac = - loraNetDevice->GetMac ()->GetObject (); + // Get the MAC + Ptr edLorawanMac = + loraNetDevice->GetMac()->GetObject(); - // Update the NetworkStatus about the existence of this node - m_status->AddNode (edLorawanMac); + // Update the NetworkStatus about the existence of this node + m_status->AddNode(edLorawanMac); } bool -NetworkServer::Receive (Ptr device, Ptr packet, - uint16_t protocol, const Address& address) +NetworkServer::Receive(Ptr device, + Ptr packet, + uint16_t protocol, + const Address& address) { - NS_LOG_FUNCTION (this << packet << protocol << address); + NS_LOG_FUNCTION(this << packet << protocol << address); - // Create a copy of the packet - Ptr myPacket = packet->Copy (); + // Create a copy of the packet + Ptr myPacket = packet->Copy(); - // Fire the trace source - m_receivedPacket (packet); + // Fire the trace source + m_receivedPacket(packet); - // Inform the scheduler of the newly arrived packet - m_scheduler->OnReceivedPacket (packet); + // Inform the scheduler of the newly arrived packet + m_scheduler->OnReceivedPacket(packet); - // Inform the status of the newly arrived packet - m_status->OnReceivedPacket (packet, address); + // Inform the status of the newly arrived packet + m_status->OnReceivedPacket(packet, address); - // Inform the controller of the newly arrived packet - m_controller->OnNewPacket (packet); + // Inform the controller of the newly arrived packet + m_controller->OnNewPacket(packet); - return true; + return true; } void -NetworkServer::AddComponent (Ptr component) +NetworkServer::AddComponent(Ptr component) { - NS_LOG_FUNCTION (this << component); + NS_LOG_FUNCTION(this << component); - m_controller->Install (component); + m_controller->Install(component); } Ptr -NetworkServer::GetNetworkStatus (void) +NetworkServer::GetNetworkStatus(void) { - return m_status; + return m_status; } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/network-server.h b/model/network-server.h index 3610d4a364..9f51c240c5 100644 --- a/model/network-server.h +++ b/model/network-server.h @@ -22,22 +22,25 @@ #ifndef NETWORK_SERVER_H #define NETWORK_SERVER_H -#include "ns3/object.h" +#include "class-a-end-device-lorawan-mac.h" +#include "gateway-status.h" +#include "lora-device-address.h" +#include "network-controller.h" +#include "network-scheduler.h" +#include "network-status.h" + #include "ns3/application.h" +#include "ns3/log.h" #include "ns3/net-device.h" -#include "ns3/point-to-point-net-device.h" -#include "ns3/packet.h" -#include "ns3/lora-device-address.h" -#include "ns3/gateway-status.h" -#include "ns3/network-status.h" -#include "ns3/network-scheduler.h" -#include "ns3/network-controller.h" #include "ns3/node-container.h" -#include "ns3/log.h" -#include "ns3/class-a-end-device-lorawan-mac.h" +#include "ns3/object.h" +#include "ns3/packet.h" +#include "ns3/point-to-point-net-device.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * The NetworkServer is an application standing on top of a node equipped with @@ -48,63 +51,65 @@ namespace lorawan { */ class NetworkServer : public Application { -public: - static TypeId GetTypeId (void); - - NetworkServer (); - virtual ~NetworkServer (); - - /** - * Start the NS application. - */ - void StartApplication (void); - - /** - * Stop the NS application. - */ - void StopApplication (void); - - /** - * Inform the NetworkServer that these nodes are connected to the network. - * - * This method will create a DeviceStatus object for each new node, and add - * it to the list. - */ - void AddNodes (NodeContainer nodes); - - /** - * Inform the NetworkServer that this node is connected to the network. - * This method will create a DeviceStatus object for the new node (if it - * doesn't already exist). - */ - void AddNode (Ptr node); - - /** - * Add this gateway to the list of gateways connected to this NS. - * Each GW is identified by its Address in the NS-GWs network. - */ - void AddGateway (Ptr gateway, Ptr netDevice); - - /** - * A NetworkControllerComponent to this NetworkServer instance. - */ - void AddComponent (Ptr component); - - /** - * Receive a packet from a gateway. - * \param packet the received packet - */ - bool Receive (Ptr device, Ptr packet, uint16_t protocol, - const Address &address); - - Ptr GetNetworkStatus (void); - -protected: - Ptr m_status; - Ptr m_controller; - Ptr m_scheduler; - - TracedCallback> m_receivedPacket; + public: + static TypeId GetTypeId(void); + + NetworkServer(); + virtual ~NetworkServer(); + + /** + * Start the NS application. + */ + void StartApplication(void); + + /** + * Stop the NS application. + */ + void StopApplication(void); + + /** + * Inform the NetworkServer that these nodes are connected to the network. + * + * This method will create a DeviceStatus object for each new node, and add + * it to the list. + */ + void AddNodes(NodeContainer nodes); + + /** + * Inform the NetworkServer that this node is connected to the network. + * This method will create a DeviceStatus object for the new node (if it + * doesn't already exist). + */ + void AddNode(Ptr node); + + /** + * Add this gateway to the list of gateways connected to this NS. + * Each GW is identified by its Address in the NS-GWs network. + */ + void AddGateway(Ptr gateway, Ptr netDevice); + + /** + * A NetworkControllerComponent to this NetworkServer instance. + */ + void AddComponent(Ptr component); + + /** + * Receive a packet from a gateway. + * \param packet the received packet + */ + bool Receive(Ptr device, + Ptr packet, + uint16_t protocol, + const Address& address); + + Ptr GetNetworkStatus(void); + + protected: + Ptr m_status; + Ptr m_controller; + Ptr m_scheduler; + + TracedCallback> m_receivedPacket; }; } // namespace lorawan diff --git a/model/network-status.cc b/model/network-status.cc index 2f6995e720..74c1d4cda3 100644 --- a/model/network-status.cc +++ b/model/network-status.cc @@ -19,233 +19,231 @@ * Martina Capuzzo */ -#include "ns3/network-status.h" -#include "ns3/end-device-status.h" -#include "ns3/gateway-status.h" +#include "network-status.h" +#include "end-device-status.h" +#include "gateway-status.h" +#include "lora-device-address.h" + +#include "ns3/log.h" #include "ns3/net-device.h" -#include "ns3/packet.h" -#include "ns3/lora-device-address.h" #include "ns3/node-container.h" -#include "ns3/log.h" +#include "ns3/packet.h" #include "ns3/pointer.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("NetworkStatus"); +NS_LOG_COMPONENT_DEFINE("NetworkStatus"); -NS_OBJECT_ENSURE_REGISTERED (NetworkStatus); +NS_OBJECT_ENSURE_REGISTERED(NetworkStatus); TypeId -NetworkStatus::GetTypeId (void) +NetworkStatus::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::NetworkStatus") - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = + TypeId("ns3::NetworkStatus").AddConstructor().SetGroupName("lorawan"); + return tid; } -NetworkStatus::NetworkStatus () +NetworkStatus::NetworkStatus() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -NetworkStatus::~NetworkStatus () +NetworkStatus::~NetworkStatus() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -NetworkStatus::AddNode (Ptr edMac) +NetworkStatus::AddNode(Ptr edMac) { - NS_LOG_FUNCTION (this << edMac); + NS_LOG_FUNCTION(this << edMac); - // Check whether this device already exists in our list - LoraDeviceAddress edAddress = edMac->GetDeviceAddress (); - if (m_endDeviceStatuses.find (edAddress) == m_endDeviceStatuses.end ()) + // Check whether this device already exists in our list + LoraDeviceAddress edAddress = edMac->GetDeviceAddress(); + if (m_endDeviceStatuses.find(edAddress) == m_endDeviceStatuses.end()) { - // The device doesn't exist. Create new EndDeviceStatus - Ptr edStatus = CreateObject - (edAddress, edMac->GetObject()); - - // Add it to the map - m_endDeviceStatuses.insert (std::pair > - (edAddress, edStatus)); - NS_LOG_DEBUG ("Added to the list a device with address " << - edAddress.Print ()); + // The device doesn't exist. Create new EndDeviceStatus + Ptr edStatus = + CreateObject(edAddress, edMac->GetObject()); + + // Add it to the map + m_endDeviceStatuses.insert( + std::pair>(edAddress, edStatus)); + NS_LOG_DEBUG("Added to the list a device with address " << edAddress.Print()); } } void -NetworkStatus::AddGateway (Address& address, Ptr gwStatus) +NetworkStatus::AddGateway(Address& address, Ptr gwStatus) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Check whether this device already exists in the list - if (m_gatewayStatuses.find (address) == m_gatewayStatuses.end ()) + // Check whether this device already exists in the list + if (m_gatewayStatuses.find(address) == m_gatewayStatuses.end()) { - // The device doesn't exist. + // The device doesn't exist. - // Add it to the map - m_gatewayStatuses.insert (std::pair > - (address, gwStatus)); - NS_LOG_DEBUG ("Added to the list a gateway with address " << address); + // Add it to the map + m_gatewayStatuses.insert(std::pair>(address, gwStatus)); + NS_LOG_DEBUG("Added to the list a gateway with address " << address); } } void -NetworkStatus::OnReceivedPacket (Ptr packet, - const Address& gwAddress) +NetworkStatus::OnReceivedPacket(Ptr packet, const Address& gwAddress) { - NS_LOG_FUNCTION (this << packet << gwAddress); - - // Create a copy of the packet - Ptr myPacket = packet->Copy (); - - // Extract the headers - LorawanMacHeader macHdr; - myPacket->RemoveHeader (macHdr); - LoraFrameHeader frameHdr; - frameHdr.SetAsUplink (); - myPacket->RemoveHeader (frameHdr); - - // Update the correct EndDeviceStatus object - LoraDeviceAddress edAddr = frameHdr.GetAddress (); - NS_LOG_DEBUG ("Node address: " << edAddr); - m_endDeviceStatuses.at (edAddr)->InsertReceivedPacket (packet, gwAddress); + NS_LOG_FUNCTION(this << packet << gwAddress); + + // Create a copy of the packet + Ptr myPacket = packet->Copy(); + + // Extract the headers + LorawanMacHeader macHdr; + myPacket->RemoveHeader(macHdr); + LoraFrameHeader frameHdr; + frameHdr.SetAsUplink(); + myPacket->RemoveHeader(frameHdr); + + // Update the correct EndDeviceStatus object + LoraDeviceAddress edAddr = frameHdr.GetAddress(); + NS_LOG_DEBUG("Node address: " << edAddr); + m_endDeviceStatuses.at(edAddr)->InsertReceivedPacket(packet, gwAddress); } bool -NetworkStatus::NeedsReply (LoraDeviceAddress deviceAddress) +NetworkStatus::NeedsReply(LoraDeviceAddress deviceAddress) { - // Throws out of range if no device is found - return m_endDeviceStatuses.at (deviceAddress)->NeedsReply (); + // Throws out of range if no device is found + return m_endDeviceStatuses.at(deviceAddress)->NeedsReply(); } Address -NetworkStatus::GetBestGatewayForDevice (LoraDeviceAddress deviceAddress, int window) +NetworkStatus::GetBestGatewayForDevice(LoraDeviceAddress deviceAddress, int window) { - // Get the endDeviceStatus we are interested in - Ptr edStatus = m_endDeviceStatuses.at (deviceAddress); - double replyFrequency; - if (window == 1) + // Get the endDeviceStatus we are interested in + Ptr edStatus = m_endDeviceStatuses.at(deviceAddress); + double replyFrequency; + if (window == 1) { - replyFrequency = edStatus->GetFirstReceiveWindowFrequency(); + replyFrequency = edStatus->GetFirstReceiveWindowFrequency(); } - else if (window == 2) + else if (window == 2) { - replyFrequency = edStatus->GetSecondReceiveWindowFrequency(); + replyFrequency = edStatus->GetSecondReceiveWindowFrequency(); } - else + else { - NS_ABORT_MSG ("Invalid window value"); + NS_ABORT_MSG("Invalid window value"); } - // Get the list of gateways that this device can reach - // NOTE: At this point, we could also take into account the whole network to - // identify the best gateway according to various metrics. For now, we just - // ask the EndDeviceStatus to pick the best gateway for us via its method. - std::map gwAddresses = edStatus->GetPowerGatewayMap (); - - // By iterating on the map in reverse, we go from the 'best' - // gateway, i.e. the one with the highest received power, to the - // worst. - Address bestGwAddress; - for (auto it = gwAddresses.rbegin(); it != gwAddresses.rend(); it++) + // Get the list of gateways that this device can reach + // NOTE: At this point, we could also take into account the whole network to + // identify the best gateway according to various metrics. For now, we just + // ask the EndDeviceStatus to pick the best gateway for us via its method. + std::map gwAddresses = edStatus->GetPowerGatewayMap(); + + // By iterating on the map in reverse, we go from the 'best' + // gateway, i.e. the one with the highest received power, to the + // worst. + Address bestGwAddress; + for (auto it = gwAddresses.rbegin(); it != gwAddresses.rend(); it++) { - bool isAvailable = m_gatewayStatuses.find(it->second)->second->IsAvailableForTransmission (replyFrequency); - if (isAvailable) + bool isAvailable = + m_gatewayStatuses.find(it->second)->second->IsAvailableForTransmission(replyFrequency); + if (isAvailable) { - bestGwAddress = it->second; - break; + bestGwAddress = it->second; + break; } } - return bestGwAddress; + return bestGwAddress; } void -NetworkStatus::SendThroughGateway (Ptr packet, Address gwAddress) +NetworkStatus::SendThroughGateway(Ptr packet, Address gwAddress) { - NS_LOG_FUNCTION (packet << gwAddress); + NS_LOG_FUNCTION(packet << gwAddress); - m_gatewayStatuses.find (gwAddress)->second->GetNetDevice ()->Send (packet, - gwAddress, - 0x0800); + m_gatewayStatuses.find(gwAddress)->second->GetNetDevice()->Send(packet, gwAddress, 0x0800); } Ptr -NetworkStatus::GetReplyForDevice (LoraDeviceAddress edAddress, int windowNumber) +NetworkStatus::GetReplyForDevice(LoraDeviceAddress edAddress, int windowNumber) { - // Get the reply packet - Ptr edStatus = m_endDeviceStatuses.find (edAddress)->second; - Ptr packet = edStatus->GetCompleteReplyPacket (); + // Get the reply packet + Ptr edStatus = m_endDeviceStatuses.find(edAddress)->second; + Ptr packet = edStatus->GetCompleteReplyPacket(); - // Apply the appropriate tag - LoraTag tag; - switch (windowNumber) + // Apply the appropriate tag + LoraTag tag; + switch (windowNumber) { case 1: - tag.SetDataRate (edStatus->GetMac ()->GetFirstReceiveWindowDataRate ()); - tag.SetFrequency (edStatus->GetFirstReceiveWindowFrequency ()); - break; + tag.SetDataRate(edStatus->GetMac()->GetFirstReceiveWindowDataRate()); + tag.SetFrequency(edStatus->GetFirstReceiveWindowFrequency()); + break; case 2: - tag.SetDataRate (edStatus->GetMac ()->GetSecondReceiveWindowDataRate ()); - tag.SetFrequency (edStatus->GetSecondReceiveWindowFrequency ()); - break; + tag.SetDataRate(edStatus->GetMac()->GetSecondReceiveWindowDataRate()); + tag.SetFrequency(edStatus->GetSecondReceiveWindowFrequency()); + break; } - packet->AddPacketTag (tag); - return packet; + packet->AddPacketTag(tag); + return packet; } Ptr -NetworkStatus::GetEndDeviceStatus (Ptr packet) +NetworkStatus::GetEndDeviceStatus(Ptr packet) { - NS_LOG_FUNCTION (this << packet); - - // Get the address - LorawanMacHeader mHdr; - LoraFrameHeader fHdr; - Ptr myPacket = packet->Copy (); - myPacket->RemoveHeader (mHdr); - myPacket->RemoveHeader (fHdr); - auto it = m_endDeviceStatuses.find (fHdr.GetAddress ()); - if (it != m_endDeviceStatuses.end ()) + NS_LOG_FUNCTION(this << packet); + + // Get the address + LorawanMacHeader mHdr; + LoraFrameHeader fHdr; + Ptr myPacket = packet->Copy(); + myPacket->RemoveHeader(mHdr); + myPacket->RemoveHeader(fHdr); + auto it = m_endDeviceStatuses.find(fHdr.GetAddress()); + if (it != m_endDeviceStatuses.end()) { - return (*it).second; + return (*it).second; } - else + else { - NS_LOG_ERROR ("EndDeviceStatus not found"); - return 0; + NS_LOG_ERROR("EndDeviceStatus not found"); + return 0; } } Ptr -NetworkStatus::GetEndDeviceStatus (LoraDeviceAddress address) +NetworkStatus::GetEndDeviceStatus(LoraDeviceAddress address) { - NS_LOG_FUNCTION (this << address); + NS_LOG_FUNCTION(this << address); - auto it = m_endDeviceStatuses.find (address); - if (it != m_endDeviceStatuses.end ()) + auto it = m_endDeviceStatuses.find(address); + if (it != m_endDeviceStatuses.end()) { - return (*it).second; + return (*it).second; } - else + else { - NS_LOG_ERROR ("EndDeviceStatus not found"); - return 0; + NS_LOG_ERROR("EndDeviceStatus not found"); + return 0; } } int -NetworkStatus::CountEndDevices (void) +NetworkStatus::CountEndDevices(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - return m_endDeviceStatuses.size (); -} -} + return m_endDeviceStatuses.size(); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/network-status.h b/model/network-status.h index 600559d602..c7824652d0 100644 --- a/model/network-status.h +++ b/model/network-status.h @@ -22,16 +22,18 @@ #ifndef NETWORK_STATUS_H #define NETWORK_STATUS_H -#include "ns3/end-device-status.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/gateway-status.h" -#include "ns3/lora-device-address.h" -#include "ns3/network-scheduler.h" +#include "class-a-end-device-lorawan-mac.h" +#include "end-device-status.h" +#include "gateway-status.h" +#include "lora-device-address.h" +#include "network-scheduler.h" #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ /** * This class represents the knowledge about the state of the network that is @@ -44,79 +46,79 @@ namespace lorawan { */ class NetworkStatus : public Object { -public: - static TypeId GetTypeId (void); - - NetworkStatus (); - virtual ~NetworkStatus (); - - /** - * Add a device to the ones that are tracked by this NetworkStatus object. - */ - void AddNode (Ptr edMac); - - /** - * Add this gateway to the list of gateways connected to the network. - * - * Each GW is identified by its Address in the NS-GW network. - */ - void AddGateway (Address &address, Ptr gwStatus); - - /** - * Update network status on the received packet. - * - * \param packet the received packet. - * \param address the gateway this packet was received from. - */ - void OnReceivedPacket (Ptr packet, const Address &gwaddress); - - /** - * Return whether the specified device needs a reply. - * - * \param deviceAddress the address of the device we are interested in. - */ - bool NeedsReply (LoraDeviceAddress deviceAddress); - - /** - * Return whether we have a gateway that is available to send a reply to the - * specified device. - * - * \param deviceAddress the address of the device we are interested in. - */ - Address GetBestGatewayForDevice (LoraDeviceAddress deviceAddress, int window); - - /** - * Send a packet through a Gateway. - * - * This function assumes that the packet is already tagged with a LoraTag - * that will inform the gateway of the parameters to use for the - * transmission. - */ - void SendThroughGateway (Ptr packet, Address gwAddress); - - /** - * Get the reply for the specified device address. - */ - Ptr GetReplyForDevice (LoraDeviceAddress edAddress, int windowNumber); - - /** - * Get the EndDeviceStatus for the device that sent a packet. - */ - Ptr GetEndDeviceStatus (Ptr packet); - - /** - * Get the EndDeviceStatus corresponding to a LoraDeviceAddress. - */ - Ptr GetEndDeviceStatus (LoraDeviceAddress address); - - /** - * Return the number of end devices currently managed by the server. - */ - int CountEndDevices (void); - -public: - std::map> m_endDeviceStatuses; - std::map> m_gatewayStatuses; + public: + static TypeId GetTypeId(void); + + NetworkStatus(); + virtual ~NetworkStatus(); + + /** + * Add a device to the ones that are tracked by this NetworkStatus object. + */ + void AddNode(Ptr edMac); + + /** + * Add this gateway to the list of gateways connected to the network. + * + * Each GW is identified by its Address in the NS-GW network. + */ + void AddGateway(Address& address, Ptr gwStatus); + + /** + * Update network status on the received packet. + * + * \param packet the received packet. + * \param address the gateway this packet was received from. + */ + void OnReceivedPacket(Ptr packet, const Address& gwaddress); + + /** + * Return whether the specified device needs a reply. + * + * \param deviceAddress the address of the device we are interested in. + */ + bool NeedsReply(LoraDeviceAddress deviceAddress); + + /** + * Return whether we have a gateway that is available to send a reply to the + * specified device. + * + * \param deviceAddress the address of the device we are interested in. + */ + Address GetBestGatewayForDevice(LoraDeviceAddress deviceAddress, int window); + + /** + * Send a packet through a Gateway. + * + * This function assumes that the packet is already tagged with a LoraTag + * that will inform the gateway of the parameters to use for the + * transmission. + */ + void SendThroughGateway(Ptr packet, Address gwAddress); + + /** + * Get the reply for the specified device address. + */ + Ptr GetReplyForDevice(LoraDeviceAddress edAddress, int windowNumber); + + /** + * Get the EndDeviceStatus for the device that sent a packet. + */ + Ptr GetEndDeviceStatus(Ptr packet); + + /** + * Get the EndDeviceStatus corresponding to a LoraDeviceAddress. + */ + Ptr GetEndDeviceStatus(LoraDeviceAddress address); + + /** + * Return the number of end devices currently managed by the server. + */ + int CountEndDevices(void); + + public: + std::map> m_endDeviceStatuses; + std::map> m_gatewayStatuses; }; } // namespace lorawan diff --git a/model/one-shot-sender.cc b/model/one-shot-sender.cc index 24143836bf..006bc38703 100644 --- a/model/one-shot-sender.cc +++ b/model/one-shot-sender.cc @@ -18,91 +18,94 @@ * Author: Davide Magrin */ -#include "ns3/one-shot-sender.h" -#include "ns3/class-a-end-device-lorawan-mac.h" -#include "ns3/pointer.h" -#include "ns3/log.h" +#include "one-shot-sender.h" + +#include "class-a-end-device-lorawan-mac.h" +#include "lora-net-device.h" + #include "ns3/double.h" +#include "ns3/log.h" +#include "ns3/pointer.h" #include "ns3/string.h" -#include "ns3/lora-net-device.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("OneShotSender"); +NS_LOG_COMPONENT_DEFINE("OneShotSender"); -NS_OBJECT_ENSURE_REGISTERED (OneShotSender); +NS_OBJECT_ENSURE_REGISTERED(OneShotSender); TypeId -OneShotSender::GetTypeId (void) +OneShotSender::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::OneShotSender") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan"); - return tid; + static TypeId tid = TypeId("ns3::OneShotSender") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan"); + return tid; } -OneShotSender::OneShotSender () +OneShotSender::OneShotSender() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -OneShotSender::OneShotSender (Time sendTime) - : m_sendTime (sendTime) +OneShotSender::OneShotSender(Time sendTime) + : m_sendTime(sendTime) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -OneShotSender::~OneShotSender () +OneShotSender::~OneShotSender() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -OneShotSender::SetSendTime (Time sendTime) +OneShotSender::SetSendTime(Time sendTime) { - NS_LOG_FUNCTION (this << sendTime); + NS_LOG_FUNCTION(this << sendTime); - m_sendTime = sendTime; + m_sendTime = sendTime; } void -OneShotSender::SendPacket (void) +OneShotSender::SendPacket(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Create and send a new packet - Ptr packet = Create (10); - m_mac->Send (packet); + // Create and send a new packet + Ptr packet = Create(10); + m_mac->Send(packet); } void -OneShotSender::StartApplication (void) +OneShotSender::StartApplication(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Make sure we have a MAC layer - if (!m_mac) + // Make sure we have a MAC layer + if (!m_mac) { - // Assumes there's only one device - Ptr loraNetDevice = m_node->GetDevice (0)->GetObject (); + // Assumes there's only one device + Ptr loraNetDevice = m_node->GetDevice(0)->GetObject(); - m_mac = loraNetDevice->GetMac (); - NS_ASSERT (m_mac); + m_mac = loraNetDevice->GetMac(); + NS_ASSERT(m_mac); } - // Schedule the next SendPacket event - Simulator::Cancel (m_sendEvent); - m_sendEvent = Simulator::Schedule (m_sendTime, &OneShotSender::SendPacket, - this); + // Schedule the next SendPacket event + Simulator::Cancel(m_sendEvent); + m_sendEvent = Simulator::Schedule(m_sendTime, &OneShotSender::SendPacket, this); } void -OneShotSender::StopApplication (void) +OneShotSender::StopApplication(void) { - NS_LOG_FUNCTION_NOARGS (); - Simulator::Cancel (m_sendEvent); -} -} + NS_LOG_FUNCTION_NOARGS(); + Simulator::Cancel(m_sendEvent); } +} // namespace lorawan +} // namespace ns3 diff --git a/model/one-shot-sender.h b/model/one-shot-sender.h index a3be66c8b6..1cd13a9d1d 100644 --- a/model/one-shot-sender.h +++ b/model/one-shot-sender.h @@ -21,61 +21,64 @@ #ifndef ONE_SHOT_SENDER_H #define ONE_SHOT_SENDER_H +#include "lorawan-mac.h" + #include "ns3/application.h" -#include "ns3/nstime.h" -#include "ns3/lorawan-mac.h" #include "ns3/attribute.h" +#include "ns3/nstime.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class OneShotSender : public Application { -public: - OneShotSender (); - OneShotSender (Time sendTime); - ~OneShotSender (); + public: + OneShotSender(); + OneShotSender(Time sendTime); + ~OneShotSender(); - static TypeId GetTypeId (void); + static TypeId GetTypeId(void); - /** - * Send a packet using the LoraNetDevice's Send method. - */ - void SendPacket (void); + /** + * Send a packet using the LoraNetDevice's Send method. + */ + void SendPacket(void); - /** - * Set the time at which this app will send a packet. - */ - void SetSendTime (Time sendTime); + /** + * Set the time at which this app will send a packet. + */ + void SetSendTime(Time sendTime); - /** - * Start the application by scheduling the first SendPacket event. - */ - void StartApplication (void); + /** + * Start the application by scheduling the first SendPacket event. + */ + void StartApplication(void); - /** - * Stop the application. - */ - void StopApplication (void); + /** + * Stop the application. + */ + void StopApplication(void); -private: - /** - * The time at which to send the packet. - */ - Time m_sendTime; + private: + /** + * The time at which to send the packet. + */ + Time m_sendTime; - /** - * The sending event. - */ - EventId m_sendEvent; + /** + * The sending event. + */ + EventId m_sendEvent; - /** - * The MAC layer of this node. - */ - Ptr m_mac; + /** + * The MAC layer of this node. + */ + Ptr m_mac; }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* ONE_SHOT_APPLICATION */ diff --git a/model/periodic-sender.cc b/model/periodic-sender.cc index fed5dd7c89..82b8929efd 100644 --- a/model/periodic-sender.cc +++ b/model/periodic-sender.cc @@ -18,145 +18,146 @@ * Author: Davide Magrin */ -#include "ns3/periodic-sender.h" -#include "ns3/pointer.h" -#include "ns3/log.h" +#include "periodic-sender.h" + +#include "lora-net-device.h" + #include "ns3/double.h" +#include "ns3/log.h" +#include "ns3/pointer.h" #include "ns3/string.h" -#include "ns3/lora-net-device.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("PeriodicSender"); +NS_LOG_COMPONENT_DEFINE("PeriodicSender"); -NS_OBJECT_ENSURE_REGISTERED (PeriodicSender); +NS_OBJECT_ENSURE_REGISTERED(PeriodicSender); TypeId -PeriodicSender::GetTypeId (void) +PeriodicSender::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::PeriodicSender") - .SetParent () - .AddConstructor () - .SetGroupName ("lorawan") - .AddAttribute ("Interval", "The interval between packet sends of this app", - TimeValue (Seconds (0)), - MakeTimeAccessor (&PeriodicSender::GetInterval, - &PeriodicSender::SetInterval), - MakeTimeChecker ()); - // .AddAttribute ("PacketSizeRandomVariable", "The random variable that determines the shape of the packet size, in bytes", - // StringValue ("ns3::UniformRandomVariable[Min=0,Max=10]"), - // MakePointerAccessor (&PeriodicSender::m_pktSizeRV), - // MakePointerChecker ()); - return tid; + static TypeId tid = TypeId("ns3::PeriodicSender") + .SetParent() + .AddConstructor() + .SetGroupName("lorawan") + .AddAttribute("Interval", + "The interval between packet sends of this app", + TimeValue(Seconds(0)), + MakeTimeAccessor(&PeriodicSender::GetInterval, + &PeriodicSender::SetInterval), + MakeTimeChecker()); + // .AddAttribute ("PacketSizeRandomVariable", "The random variable that determines the shape of + // the packet size, in bytes", + // StringValue ("ns3::UniformRandomVariable[Min=0,Max=10]"), + // MakePointerAccessor (&PeriodicSender::m_pktSizeRV), + // MakePointerChecker ()); + return tid; } -PeriodicSender::PeriodicSender () - : m_interval (Seconds (10)), - m_initialDelay (Seconds (1)), - m_basePktSize (10), - m_pktSizeRV (0) +PeriodicSender::PeriodicSender() + : m_interval(Seconds(10)), + m_initialDelay(Seconds(1)), + m_basePktSize(10), + m_pktSizeRV(0) { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -PeriodicSender::~PeriodicSender () +PeriodicSender::~PeriodicSender() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -PeriodicSender::SetInterval (Time interval) +PeriodicSender::SetInterval(Time interval) { - NS_LOG_FUNCTION (this << interval); - m_interval = interval; + NS_LOG_FUNCTION(this << interval); + m_interval = interval; } Time -PeriodicSender::GetInterval (void) const +PeriodicSender::GetInterval(void) const { - NS_LOG_FUNCTION (this); - return m_interval; + NS_LOG_FUNCTION(this); + return m_interval; } void -PeriodicSender::SetInitialDelay (Time delay) +PeriodicSender::SetInitialDelay(Time delay) { - NS_LOG_FUNCTION (this << delay); - m_initialDelay = delay; + NS_LOG_FUNCTION(this << delay); + m_initialDelay = delay; } - void -PeriodicSender::SetPacketSizeRandomVariable (Ptr rv) +PeriodicSender::SetPacketSizeRandomVariable(Ptr rv) { - m_pktSizeRV = rv; + m_pktSizeRV = rv; } - void -PeriodicSender::SetPacketSize (uint8_t size) +PeriodicSender::SetPacketSize(uint8_t size) { - m_basePktSize = size; + m_basePktSize = size; } - void -PeriodicSender::SendPacket (void) +PeriodicSender::SendPacket(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Create and send a new packet - Ptr packet; - if (m_pktSizeRV) + // Create and send a new packet + Ptr packet; + if (m_pktSizeRV) { - int randomsize = m_pktSizeRV->GetInteger (); - packet = Create (m_basePktSize + randomsize); + int randomsize = m_pktSizeRV->GetInteger(); + packet = Create(m_basePktSize + randomsize); } - else + else { - packet = Create (m_basePktSize); + packet = Create(m_basePktSize); } - m_mac->Send (packet); + m_mac->Send(packet); - // Schedule the next SendPacket event - m_sendEvent = Simulator::Schedule (m_interval, &PeriodicSender::SendPacket, - this); + // Schedule the next SendPacket event + m_sendEvent = Simulator::Schedule(m_interval, &PeriodicSender::SendPacket, this); - NS_LOG_DEBUG ("Sent a packet of size " << packet->GetSize ()); + NS_LOG_DEBUG("Sent a packet of size " << packet->GetSize()); } void -PeriodicSender::StartApplication (void) +PeriodicSender::StartApplication(void) { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); - // Make sure we have a MAC layer - if (m_mac) + // Make sure we have a MAC layer + if (m_mac) { - // Assumes there's only one device - Ptr loraNetDevice = m_node->GetDevice (0)->GetObject (); + // Assumes there's only one device + Ptr loraNetDevice = m_node->GetDevice(0)->GetObject(); - m_mac = loraNetDevice->GetMac (); - NS_ASSERT (m_mac); + m_mac = loraNetDevice->GetMac(); + NS_ASSERT(m_mac); } - // Schedule the next SendPacket event - Simulator::Cancel (m_sendEvent); - NS_LOG_DEBUG ("Starting up application with a first event with a " << - m_initialDelay.GetSeconds () << " seconds delay"); - m_sendEvent = Simulator::Schedule (m_initialDelay, - &PeriodicSender::SendPacket, this); - NS_LOG_DEBUG ("Event Id: " << m_sendEvent.GetUid ()); + // Schedule the next SendPacket event + Simulator::Cancel(m_sendEvent); + NS_LOG_DEBUG("Starting up application with a first event with a " << m_initialDelay.GetSeconds() + << " seconds delay"); + m_sendEvent = Simulator::Schedule(m_initialDelay, &PeriodicSender::SendPacket, this); + NS_LOG_DEBUG("Event Id: " << m_sendEvent.GetUid()); } void -PeriodicSender::StopApplication (void) +PeriodicSender::StopApplication(void) { - NS_LOG_FUNCTION_NOARGS (); - Simulator::Cancel (m_sendEvent); + NS_LOG_FUNCTION_NOARGS(); + Simulator::Cancel(m_sendEvent); } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/periodic-sender.h b/model/periodic-sender.h index ccf17528b9..be304f45cd 100644 --- a/model/periodic-sender.h +++ b/model/periodic-sender.h @@ -21,100 +21,100 @@ #ifndef PERIODIC_SENDER_H #define PERIODIC_SENDER_H +#include "lorawan-mac.h" + #include "ns3/application.h" -#include "ns3/nstime.h" -#include "ns3/lorawan-mac.h" #include "ns3/attribute.h" +#include "ns3/nstime.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class PeriodicSender : public Application { -public: - PeriodicSender (); - ~PeriodicSender (); - - static TypeId GetTypeId (void); - - /** - * Set the sending interval - * \param interval the interval between two packet sendings - */ - void SetInterval (Time interval); - - /** - * Get the sending inteval - * \returns the interval between two packet sends - */ - Time GetInterval (void) const; - - /** - * Set the initial delay of this application - */ - void SetInitialDelay (Time delay); - - /** - * Set packet size - */ - void SetPacketSize (uint8_t size); - - /** - * Set if using randomness in the packet size - */ - void SetPacketSizeRandomVariable (Ptr rv); - - /** - * Send a packet using the LoraNetDevice's Send method - */ - void SendPacket (void); - - /** - * Start the application by scheduling the first SendPacket event - */ - void StartApplication (void); - - /** - * Stop the application - */ - void StopApplication (void); - -private: - /** - * The interval between to consecutive send events - */ - Time m_interval; - - /** - * The initial delay of this application - */ - Time m_initialDelay; - - /** - * The sending event scheduled as next - */ - EventId m_sendEvent; - - /** - * The MAC layer of this node - */ - Ptr m_mac; - - /** - * The packet size. - */ - uint8_t m_basePktSize; - - - /** - * The random variable that adds bytes to the packet size - */ - Ptr m_pktSizeRV; - - + public: + PeriodicSender(); + ~PeriodicSender(); + + static TypeId GetTypeId(void); + + /** + * Set the sending interval + * \param interval the interval between two packet sendings + */ + void SetInterval(Time interval); + + /** + * Get the sending inteval + * \returns the interval between two packet sends + */ + Time GetInterval(void) const; + + /** + * Set the initial delay of this application + */ + void SetInitialDelay(Time delay); + + /** + * Set packet size + */ + void SetPacketSize(uint8_t size); + + /** + * Set if using randomness in the packet size + */ + void SetPacketSizeRandomVariable(Ptr rv); + + /** + * Send a packet using the LoraNetDevice's Send method + */ + void SendPacket(void); + + /** + * Start the application by scheduling the first SendPacket event + */ + void StartApplication(void); + + /** + * Stop the application + */ + void StopApplication(void); + + private: + /** + * The interval between to consecutive send events + */ + Time m_interval; + + /** + * The initial delay of this application + */ + Time m_initialDelay; + + /** + * The sending event scheduled as next + */ + EventId m_sendEvent; + + /** + * The MAC layer of this node + */ + Ptr m_mac; + + /** + * The packet size. + */ + uint8_t m_basePktSize; + + /** + * The random variable that adds bytes to the packet size + */ + Ptr m_pktSizeRV; }; -} //namespace ns3 +} // namespace lorawan -} +} // namespace ns3 #endif /* SENDER_APPLICATION */ diff --git a/model/simple-end-device-lora-phy.cc b/model/simple-end-device-lora-phy.cc index 2010cddac1..235426da45 100644 --- a/model/simple-end-device-lora-phy.cc +++ b/model/simple-end-device-lora-phy.cc @@ -18,142 +18,146 @@ * Author: Davide Magrin */ -#include -#include "ns3/simple-end-device-lora-phy.h" -#include "ns3/simulator.h" -#include "ns3/lora-tag.h" +#include "simple-end-device-lora-phy.h" + +#include "lora-tag.h" + #include "ns3/log.h" +#include "ns3/simulator.h" + +#include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("SimpleEndDeviceLoraPhy"); +NS_LOG_COMPONENT_DEFINE("SimpleEndDeviceLoraPhy"); -NS_OBJECT_ENSURE_REGISTERED (SimpleEndDeviceLoraPhy); +NS_OBJECT_ENSURE_REGISTERED(SimpleEndDeviceLoraPhy); TypeId -SimpleEndDeviceLoraPhy::GetTypeId (void) +SimpleEndDeviceLoraPhy::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::SimpleEndDeviceLoraPhy") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor (); + static TypeId tid = TypeId("ns3::SimpleEndDeviceLoraPhy") + .SetParent() + .SetGroupName("lorawan") + .AddConstructor(); - return tid; + return tid; } // Initialize the device with some common settings. // These will then be changed by helpers. -SimpleEndDeviceLoraPhy::SimpleEndDeviceLoraPhy () +SimpleEndDeviceLoraPhy::SimpleEndDeviceLoraPhy() { } -SimpleEndDeviceLoraPhy::~SimpleEndDeviceLoraPhy () +SimpleEndDeviceLoraPhy::~SimpleEndDeviceLoraPhy() { } void -SimpleEndDeviceLoraPhy::Send (Ptr packet, LoraTxParameters txParams, - double frequencyMHz, double txPowerDbm) +SimpleEndDeviceLoraPhy::Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm) { - NS_LOG_FUNCTION (this << packet << txParams << frequencyMHz << txPowerDbm); + NS_LOG_FUNCTION(this << packet << txParams << frequencyMHz << txPowerDbm); - NS_LOG_INFO ("Current state: " << m_state); + NS_LOG_INFO("Current state: " << m_state); - // We must be either in STANDBY or SLEEP mode to send a packet - if (m_state != STANDBY && m_state != SLEEP) + // We must be either in STANDBY or SLEEP mode to send a packet + if (m_state != STANDBY && m_state != SLEEP) { - NS_LOG_INFO ("Cannot send because device is currently not in STANDBY or SLEEP mode"); - return; + NS_LOG_INFO("Cannot send because device is currently not in STANDBY or SLEEP mode"); + return; } - // Compute the duration of the transmission - Time duration = GetOnAirTime (packet, txParams); + // Compute the duration of the transmission + Time duration = GetOnAirTime(packet, txParams); - // We can send the packet: switch to the TX state - SwitchToTx (txPowerDbm); + // We can send the packet: switch to the TX state + SwitchToTx(txPowerDbm); - // Tag the packet with information about its Spreading Factor - LoraTag tag; - packet->RemovePacketTag (tag); - tag.SetSpreadingFactor (txParams.sf); - packet->AddPacketTag (tag); + // Tag the packet with information about its Spreading Factor + LoraTag tag; + packet->RemovePacketTag(tag); + tag.SetSpreadingFactor(txParams.sf); + packet->AddPacketTag(tag); - // Send the packet over the channel - NS_LOG_INFO ("Sending the packet in the channel"); - m_channel->Send (this, packet, txPowerDbm, txParams, duration, frequencyMHz); + // Send the packet over the channel + NS_LOG_INFO("Sending the packet in the channel"); + m_channel->Send(this, packet, txPowerDbm, txParams, duration, frequencyMHz); - // Schedule the switch back to STANDBY mode. - // For reference see SX1272 datasheet, section 4.1.6 - Simulator::Schedule (duration, &EndDeviceLoraPhy::SwitchToStandby, this); + // Schedule the switch back to STANDBY mode. + // For reference see SX1272 datasheet, section 4.1.6 + Simulator::Schedule(duration, &EndDeviceLoraPhy::SwitchToStandby, this); - // Schedule the txFinished callback, if it was set - // The call is scheduled just after the switch to standby in case the upper - // layer wishes to change the state. This ensures that it will find a PHY in - // STANDBY mode. - if (!m_txFinishedCallback.IsNull ()) + // Schedule the txFinished callback, if it was set + // The call is scheduled just after the switch to standby in case the upper + // layer wishes to change the state. This ensures that it will find a PHY in + // STANDBY mode. + if (!m_txFinishedCallback.IsNull()) { - Simulator::Schedule (duration + NanoSeconds (10), - &SimpleEndDeviceLoraPhy::m_txFinishedCallback, this, - packet); + Simulator::Schedule(duration + NanoSeconds(10), + &SimpleEndDeviceLoraPhy::m_txFinishedCallback, + this, + packet); } - - // Call the trace source - if (m_device) + // Call the trace source + if (m_device) { - m_startSending (packet, m_device->GetNode ()->GetId ()); + m_startSending(packet, m_device->GetNode()->GetId()); } - else + else { - m_startSending (packet, 0); + m_startSending(packet, 0); } } void -SimpleEndDeviceLoraPhy::StartReceive (Ptr packet, double rxPowerDbm, - uint8_t sf, Time duration, double frequencyMHz) +SimpleEndDeviceLoraPhy::StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz) { + NS_LOG_FUNCTION(this << packet << rxPowerDbm << unsigned(sf) << duration << frequencyMHz); - NS_LOG_FUNCTION (this << packet << rxPowerDbm << unsigned (sf) << duration << - frequencyMHz); - - // Notify the LoraInterferenceHelper of the impinging signal, and remember - // the event it creates. This will be used then to correctly handle the end - // of reception event. - // - // We need to do this regardless of our state or frequency, since these could - // change (and making the interference relevant) while the interference is - // still incoming. + // Notify the LoraInterferenceHelper of the impinging signal, and remember + // the event it creates. This will be used then to correctly handle the end + // of reception event. + // + // We need to do this regardless of our state or frequency, since these could + // change (and making the interference relevant) while the interference is + // still incoming. - Ptr event; - event = m_interference.Add (duration, rxPowerDbm, sf, packet, frequencyMHz); + Ptr event; + event = m_interference.Add(duration, rxPowerDbm, sf, packet, frequencyMHz); - // Switch on the current PHY state - switch (m_state) + // Switch on the current PHY state + switch (m_state) { // In the SLEEP, TX and RX cases we cannot receive the packet: we only add // it to the list of interferers and do not schedule an EndReceive event for // it. - case SLEEP: - { - NS_LOG_INFO ("Dropping packet because device is in SLEEP state"); + case SLEEP: { + NS_LOG_INFO("Dropping packet because device is in SLEEP state"); break; - } - case TX: - { - NS_LOG_INFO ("Dropping packet because device is in TX state"); + } + case TX: { + NS_LOG_INFO("Dropping packet because device is in TX state"); break; - } - case RX: - { - NS_LOG_INFO ("Dropping packet because device is already in RX state"); + } + case RX: { + NS_LOG_INFO("Dropping packet because device is already in RX state"); break; - } + } // If we are in STANDBY mode, we can potentially lock on the currently // incoming transmission - case STANDBY: - { + case STANDBY: { // There are a series of properties the packet needs to respect in order // for us to be able to lock on it: // - It's on frequency we are listening on @@ -168,146 +172,142 @@ SimpleEndDeviceLoraPhy::StartReceive (Ptr packet, double rxPowerDbm, // Check frequency ////////////////// - if (!IsOnFrequency (frequencyMHz)) - { - NS_LOG_INFO ("Packet lost because it's on frequency " << - frequencyMHz << " MHz and we are listening at " << - m_frequency << " MHz"); + if (!IsOnFrequency(frequencyMHz)) + { + NS_LOG_INFO("Packet lost because it's on frequency " + << frequencyMHz << " MHz and we are listening at " << m_frequency + << " MHz"); // Fire the trace source for this event. if (m_device) - { - m_wrongFrequency (packet, m_device->GetNode ()->GetId ()); - } + { + m_wrongFrequency(packet, m_device->GetNode()->GetId()); + } else - { - m_wrongFrequency (packet, 0); - } + { + m_wrongFrequency(packet, 0); + } canLockOnPacket = false; - } + } // Check Spreading Factor ///////////////////////// if (sf != m_sf) - { - NS_LOG_INFO ("Packet lost because it's using SF" << unsigned(sf) << - ", while we are listening for SF" << unsigned(m_sf)); + { + NS_LOG_INFO("Packet lost because it's using SF" + << unsigned(sf) << ", while we are listening for SF" << unsigned(m_sf)); // Fire the trace source for this event. if (m_device) - { - m_wrongSf (packet, m_device->GetNode ()->GetId ()); - } + { + m_wrongSf(packet, m_device->GetNode()->GetId()); + } else - { - m_wrongSf (packet, 0); - } + { + m_wrongSf(packet, 0); + } canLockOnPacket = false; - } + } // Check Sensitivity //////////////////// if (rxPowerDbm < sensitivity) - { - NS_LOG_INFO ("Dropping packet reception of packet with sf = " << - unsigned(sf) << " because under the sensitivity of " << - sensitivity << " dBm"); + { + NS_LOG_INFO("Dropping packet reception of packet with sf = " + << unsigned(sf) << " because under the sensitivity of " << sensitivity + << " dBm"); // Fire the trace source for this event. if (m_device) - { - m_underSensitivity (packet, m_device->GetNode ()->GetId ()); - } + { + m_underSensitivity(packet, m_device->GetNode()->GetId()); + } else - { - m_underSensitivity (packet, 0); - } + { + m_underSensitivity(packet, 0); + } canLockOnPacket = false; - } + } // Check if one of the above failed /////////////////////////////////// if (canLockOnPacket) - { + { // Switch to RX state // EndReceive will handle the switch back to STANDBY state - SwitchToRx (); + SwitchToRx(); // Schedule the end of the reception of the packet - NS_LOG_INFO ("Scheduling reception of a packet. End in " << - duration.GetSeconds () << " seconds"); + NS_LOG_INFO("Scheduling reception of a packet. End in " << duration.GetSeconds() + << " seconds"); - Simulator::Schedule (duration, &LoraPhy::EndReceive, this, packet, - event); + Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event); // Fire the beginning of reception trace source - m_phyRxBeginTrace (packet); - } - } + m_phyRxBeginTrace(packet); + } + } } } void -SimpleEndDeviceLoraPhy::EndReceive (Ptr packet, - Ptr event) +SimpleEndDeviceLoraPhy::EndReceive(Ptr packet, Ptr event) { - NS_LOG_FUNCTION (this << packet << event); + NS_LOG_FUNCTION(this << packet << event); - // Automatically switch to Standby in either case - SwitchToStandby (); + // Automatically switch to Standby in either case + SwitchToStandby(); - // Fire the trace source - m_phyRxEndTrace (packet); + // Fire the trace source + m_phyRxEndTrace(packet); - // Call the LoraInterferenceHelper to determine whether there was destructive - // interference on this event. - bool packetDestroyed = m_interference.IsDestroyedByInterference (event); + // Call the LoraInterferenceHelper to determine whether there was destructive + // interference on this event. + bool packetDestroyed = m_interference.IsDestroyedByInterference(event); - // Fire the trace source if packet was destroyed - if (packetDestroyed) + // Fire the trace source if packet was destroyed + if (packetDestroyed) { - NS_LOG_INFO ("Packet destroyed by interference"); + NS_LOG_INFO("Packet destroyed by interference"); - if (m_device) + if (m_device) { - m_interferedPacket (packet, m_device->GetNode ()->GetId ()); + m_interferedPacket(packet, m_device->GetNode()->GetId()); } - else + else { - m_interferedPacket (packet, 0); + m_interferedPacket(packet, 0); } - // If there is one, perform the callback to inform the upper layer of the - // lost packet - if (!m_rxFailedCallback.IsNull ()) + // If there is one, perform the callback to inform the upper layer of the + // lost packet + if (!m_rxFailedCallback.IsNull()) { - m_rxFailedCallback (packet); + m_rxFailedCallback(packet); } - } - else + else { - NS_LOG_INFO ("Packet received correctly"); + NS_LOG_INFO("Packet received correctly"); - if (m_device) + if (m_device) { - m_successfullyReceivedPacket (packet, m_device->GetNode ()->GetId ()); + m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId()); } - else + else { - m_successfullyReceivedPacket (packet, 0); + m_successfullyReceivedPacket(packet, 0); } - // If there is one, perform the callback to inform the upper layer - if (!m_rxOkCallback.IsNull ()) + // If there is one, perform the callback to inform the upper layer + if (!m_rxOkCallback.IsNull()) { - m_rxOkCallback (packet); + m_rxOkCallback(packet); } - } } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/model/simple-end-device-lora-phy.h b/model/simple-end-device-lora-phy.h index 9df9582d4f..74b217c143 100644 --- a/model/simple-end-device-lora-phy.h +++ b/model/simple-end-device-lora-phy.h @@ -21,16 +21,19 @@ #ifndef SIMPLE_END_DEVICE_LORA_PHY_H #define SIMPLE_END_DEVICE_LORA_PHY_H -#include "ns3/object.h" -#include "ns3/traced-value.h" -#include "ns3/net-device.h" -#include "ns3/nstime.h" +#include "end-device-lora-phy.h" + #include "ns3/mobility-model.h" +#include "ns3/net-device.h" #include "ns3/node.h" -#include "ns3/end-device-lora-phy.h" +#include "ns3/nstime.h" +#include "ns3/object.h" +#include "ns3/traced-value.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; @@ -40,29 +43,33 @@ class LoraChannel; */ class SimpleEndDeviceLoraPhy : public EndDeviceLoraPhy { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); - // Constructor and destructor - SimpleEndDeviceLoraPhy (); - virtual ~SimpleEndDeviceLoraPhy (); + // Constructor and destructor + SimpleEndDeviceLoraPhy(); + virtual ~SimpleEndDeviceLoraPhy(); - // Implementation of EndDeviceLoraPhy's pure virtual functions - virtual void StartReceive (Ptr packet, double rxPowerDbm, - uint8_t sf, Time duration, double frequencyMHz); + // Implementation of EndDeviceLoraPhy's pure virtual functions + virtual void StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz); - // Implementation of LoraPhy's pure virtual functions - virtual void EndReceive (Ptr packet, - Ptr event); + // Implementation of LoraPhy's pure virtual functions + virtual void EndReceive(Ptr packet, Ptr event); - // Implementation of LoraPhy's pure virtual functions - virtual void Send (Ptr packet, LoraTxParameters txParams, - double frequencyMHz, double txPowerDbm); + // Implementation of LoraPhy's pure virtual functions + virtual void Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm); -private: + private: }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* SIMPLE_END_DEVICE_LORA_PHY_H */ diff --git a/model/simple-gateway-lora-phy.cc b/model/simple-gateway-lora-phy.cc index a08a7f9cff..0bdf8b61f3 100644 --- a/model/simple-gateway-lora-phy.cc +++ b/model/simple-gateway-lora-phy.cc @@ -18,288 +18,296 @@ * Author: Davide Magrin */ -#include "ns3/simple-gateway-lora-phy.h" -#include "ns3/lora-tag.h" -#include "ns3/simulator.h" +#include "simple-gateway-lora-phy.h" + +#include "lora-tag.h" + #include "ns3/log.h" +#include "ns3/simulator.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("SimpleGatewayLoraPhy"); +NS_LOG_COMPONENT_DEFINE("SimpleGatewayLoraPhy"); -NS_OBJECT_ENSURE_REGISTERED (SimpleGatewayLoraPhy); +NS_OBJECT_ENSURE_REGISTERED(SimpleGatewayLoraPhy); /*********************************************************************** * Implementation of Gateway methods * ***********************************************************************/ TypeId -SimpleGatewayLoraPhy::GetTypeId (void) +SimpleGatewayLoraPhy::GetTypeId(void) { - static TypeId tid = TypeId ("ns3::SimpleGatewayLoraPhy") - .SetParent () - .SetGroupName ("lorawan") - .AddConstructor (); + static TypeId tid = TypeId("ns3::SimpleGatewayLoraPhy") + .SetParent() + .SetGroupName("lorawan") + .AddConstructor(); - return tid; + return tid; } -SimpleGatewayLoraPhy::SimpleGatewayLoraPhy () +SimpleGatewayLoraPhy::SimpleGatewayLoraPhy() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } -SimpleGatewayLoraPhy::~SimpleGatewayLoraPhy () +SimpleGatewayLoraPhy::~SimpleGatewayLoraPhy() { - NS_LOG_FUNCTION_NOARGS (); + NS_LOG_FUNCTION_NOARGS(); } void -SimpleGatewayLoraPhy::Send (Ptr packet, LoraTxParameters txParams, double frequencyMHz, - double txPowerDbm) +SimpleGatewayLoraPhy::Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm) { - NS_LOG_FUNCTION (this << packet << frequencyMHz << txPowerDbm); + NS_LOG_FUNCTION(this << packet << frequencyMHz << txPowerDbm); - // Get the time a packet with these parameters will take to be transmitted - Time duration = GetOnAirTime (packet, txParams); + // Get the time a packet with these parameters will take to be transmitted + Time duration = GetOnAirTime(packet, txParams); - NS_LOG_DEBUG ("Duration of packet: " << duration << ", SF" << unsigned (txParams.sf)); + NS_LOG_DEBUG("Duration of packet: " << duration << ", SF" << unsigned(txParams.sf)); - // Interrupt all receive operations - std::list>::iterator it; - for (it = m_receptionPaths.begin (); it != m_receptionPaths.end (); ++it) + // Interrupt all receive operations + std::list>::iterator it; + for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it) { + Ptr currentPath = *it; - Ptr currentPath = *it; - - if (!currentPath->IsAvailable ()) // Reception path is occupied + if (!currentPath->IsAvailable()) // Reception path is occupied { - // Call the callback for reception interrupted by transmission - // Fire the trace source - if (m_device) + // Call the callback for reception interrupted by transmission + // Fire the trace source + if (m_device) { - m_noReceptionBecauseTransmitting (currentPath->GetEvent ()->GetPacket (), - m_device->GetNode ()->GetId ()); + m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(), + m_device->GetNode()->GetId()); } - else + else { - m_noReceptionBecauseTransmitting (currentPath->GetEvent ()->GetPacket (), 0); + m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(), 0); } - // Cancel the scheduled EndReceive call - Simulator::Cancel (currentPath->GetEndReceive ()); + // Cancel the scheduled EndReceive call + Simulator::Cancel(currentPath->GetEndReceive()); - // Free it - // This also resets all parameters like packet and endReceive call - currentPath->Free (); + // Free it + // This also resets all parameters like packet and endReceive call + currentPath->Free(); } } - // Send the packet in the channel - m_channel->Send (this, packet, txPowerDbm, txParams, duration, frequencyMHz); + // Send the packet in the channel + m_channel->Send(this, packet, txPowerDbm, txParams, duration, frequencyMHz); - Simulator::Schedule (duration, &SimpleGatewayLoraPhy::TxFinished, this, packet); + Simulator::Schedule(duration, &SimpleGatewayLoraPhy::TxFinished, this, packet); - m_isTransmitting = true; + m_isTransmitting = true; - // Fire the trace source - if (m_device) + // Fire the trace source + if (m_device) { - m_startSending (packet, m_device->GetNode ()->GetId ()); + m_startSending(packet, m_device->GetNode()->GetId()); } - else + else { - m_startSending (packet, 0); + m_startSending(packet, 0); } } void -SimpleGatewayLoraPhy::StartReceive (Ptr packet, double rxPowerDbm, uint8_t sf, - Time duration, double frequencyMHz) +SimpleGatewayLoraPhy::StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz) { - NS_LOG_FUNCTION (this << packet << rxPowerDbm << duration << frequencyMHz); + NS_LOG_FUNCTION(this << packet << rxPowerDbm << duration << frequencyMHz); - // Fire the trace source - m_phyRxBeginTrace (packet); + // Fire the trace source + m_phyRxBeginTrace(packet); - if (m_isTransmitting) + if (m_isTransmitting) { - // If we get to this point, there are no demodulators we can use - NS_LOG_INFO ("Dropping packet reception of packet with sf = " - << unsigned (sf) << " because we are in TX mode"); + // If we get to this point, there are no demodulators we can use + NS_LOG_INFO("Dropping packet reception of packet with sf = " + << unsigned(sf) << " because we are in TX mode"); - m_phyRxEndTrace (packet); + m_phyRxEndTrace(packet); - // Fire the trace source - if (m_device) + // Fire the trace source + if (m_device) { - m_noReceptionBecauseTransmitting (packet, m_device->GetNode ()->GetId ()); + m_noReceptionBecauseTransmitting(packet, m_device->GetNode()->GetId()); } - else + else { - m_noReceptionBecauseTransmitting (packet, 0); + m_noReceptionBecauseTransmitting(packet, 0); } - return; + return; } - // Add the event to the LoraInterferenceHelper - Ptr event; - event = m_interference.Add (duration, rxPowerDbm, sf, packet, frequencyMHz); + // Add the event to the LoraInterferenceHelper + Ptr event; + event = m_interference.Add(duration, rxPowerDbm, sf, packet, frequencyMHz); - // Cycle over the receive paths to check availability to receive the packet - std::list>::iterator it; + // Cycle over the receive paths to check availability to receive the packet + std::list>::iterator it; - for (it = m_receptionPaths.begin (); it != m_receptionPaths.end (); ++it) + for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it) { - Ptr currentPath = *it; + Ptr currentPath = *it; - // If the receive path is available and listening on the channel of - // interest, we have a candidate - if (currentPath->IsAvailable ()) + // If the receive path is available and listening on the channel of + // interest, we have a candidate + if (currentPath->IsAvailable()) { - // See whether the reception power is above or below the sensitivity - // for that spreading factor - double sensitivity = SimpleGatewayLoraPhy::sensitivity[unsigned (sf) - 7]; + // See whether the reception power is above or below the sensitivity + // for that spreading factor + double sensitivity = SimpleGatewayLoraPhy::sensitivity[unsigned(sf) - 7]; - if (rxPowerDbm < sensitivity) // Packet arrived below sensitivity + if (rxPowerDbm < sensitivity) // Packet arrived below sensitivity { - NS_LOG_INFO ("Dropping packet reception of packet with sf = " - << unsigned (sf) << " because under the sensitivity of " << sensitivity - << " dBm"); + NS_LOG_INFO("Dropping packet reception of packet with sf = " + << unsigned(sf) << " because under the sensitivity of " << sensitivity + << " dBm"); - if (m_device) + if (m_device) { - m_underSensitivity (packet, m_device->GetNode ()->GetId ()); + m_underSensitivity(packet, m_device->GetNode()->GetId()); } - else + else { - m_underSensitivity (packet, 0); + m_underSensitivity(packet, 0); } - // Since the packet is below sensitivity, it makes no sense to - // search for another ReceivePath - return; + // Since the packet is below sensitivity, it makes no sense to + // search for another ReceivePath + return; } - else // We have sufficient sensitivity to start receiving + else // We have sufficient sensitivity to start receiving { - NS_LOG_INFO ("Scheduling reception of a packet, " - << "occupying one demodulator"); + NS_LOG_INFO("Scheduling reception of a packet, " + << "occupying one demodulator"); - // Block this resource - currentPath->LockOnEvent (event); - m_occupiedReceptionPaths++; + // Block this resource + currentPath->LockOnEvent(event); + m_occupiedReceptionPaths++; - // Schedule the end of the reception of the packet - EventId endReceiveEventId = - Simulator::Schedule (duration, &LoraPhy::EndReceive, this, packet, event); + // Schedule the end of the reception of the packet + EventId endReceiveEventId = + Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event); - currentPath->SetEndReceive (endReceiveEventId); + currentPath->SetEndReceive(endReceiveEventId); - // Make sure we don't go on searching for other ReceivePaths - return; + // Make sure we don't go on searching for other ReceivePaths + return; } } } - // If we get to this point, there are no demodulators we can use - NS_LOG_INFO ("Dropping packet reception of packet with sf = " - << unsigned (sf) << " and frequency " << frequencyMHz - << "MHz because no suitable demodulator was found"); + // If we get to this point, there are no demodulators we can use + NS_LOG_INFO("Dropping packet reception of packet with sf = " + << unsigned(sf) << " and frequency " << frequencyMHz + << "MHz because no suitable demodulator was found"); - // Fire the trace source - if (m_device) + // Fire the trace source + if (m_device) { - m_noMoreDemodulators (packet, m_device->GetNode ()->GetId ()); + m_noMoreDemodulators(packet, m_device->GetNode()->GetId()); } - else + else { - m_noMoreDemodulators (packet, 0); + m_noMoreDemodulators(packet, 0); } } void -SimpleGatewayLoraPhy::EndReceive (Ptr packet, Ptr event) +SimpleGatewayLoraPhy::EndReceive(Ptr packet, Ptr event) { - NS_LOG_FUNCTION (this << packet << *event); + NS_LOG_FUNCTION(this << packet << *event); - // Call the trace source - m_phyRxEndTrace (packet); + // Call the trace source + m_phyRxEndTrace(packet); - // Call the LoraInterferenceHelper to determine whether there was - // destructive interference. If the packet is correctly received, this - // method returns a 0. - uint8_t packetDestroyed = 0; - packetDestroyed = m_interference.IsDestroyedByInterference (event); + // Call the LoraInterferenceHelper to determine whether there was + // destructive interference. If the packet is correctly received, this + // method returns a 0. + uint8_t packetDestroyed = 0; + packetDestroyed = m_interference.IsDestroyedByInterference(event); - // Check whether the packet was destroyed - if (packetDestroyed != uint8_t (0)) + // Check whether the packet was destroyed + if (packetDestroyed != uint8_t(0)) { - NS_LOG_DEBUG ("packetDestroyed by " << unsigned (packetDestroyed)); + NS_LOG_DEBUG("packetDestroyed by " << unsigned(packetDestroyed)); - // Update the packet's LoraTag - LoraTag tag; - packet->RemovePacketTag (tag); - tag.SetDestroyedBy (packetDestroyed); - packet->AddPacketTag (tag); + // Update the packet's LoraTag + LoraTag tag; + packet->RemovePacketTag(tag); + tag.SetDestroyedBy(packetDestroyed); + packet->AddPacketTag(tag); - // Fire the trace source - if (m_device) + // Fire the trace source + if (m_device) { - m_interferedPacket (packet, m_device->GetNode ()->GetId ()); + m_interferedPacket(packet, m_device->GetNode()->GetId()); } - else + else { - m_interferedPacket (packet, 0); + m_interferedPacket(packet, 0); } } - else // Reception was correct + else // Reception was correct { - NS_LOG_INFO ("Packet with SF " << unsigned (event->GetSpreadingFactor ()) - << " received correctly"); + NS_LOG_INFO("Packet with SF " << unsigned(event->GetSpreadingFactor()) + << " received correctly"); - // Fire the trace source - if (m_device) + // Fire the trace source + if (m_device) { - m_successfullyReceivedPacket (packet, m_device->GetNode ()->GetId ()); + m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId()); } - else + else { - m_successfullyReceivedPacket (packet, 0); + m_successfullyReceivedPacket(packet, 0); } - // Forward the packet to the upper layer - if (!m_rxOkCallback.IsNull ()) + // Forward the packet to the upper layer + if (!m_rxOkCallback.IsNull()) { - // Make a copy of the packet - // Ptr packetCopy = packet->Copy (); - - // Set the receive power and frequency of this packet in the LoraTag: this - // information can be useful for upper layers trying to control link - // quality. - LoraTag tag; - packet->RemovePacketTag (tag); - tag.SetReceivePower (event->GetRxPowerdBm ()); - tag.SetFrequency (event->GetFrequency ()); - packet->AddPacketTag (tag); - - m_rxOkCallback (packet); + // Make a copy of the packet + // Ptr packetCopy = packet->Copy (); + + // Set the receive power and frequency of this packet in the LoraTag: this + // information can be useful for upper layers trying to control link + // quality. + LoraTag tag; + packet->RemovePacketTag(tag); + tag.SetReceivePower(event->GetRxPowerdBm()); + tag.SetFrequency(event->GetFrequency()); + packet->AddPacketTag(tag); + + m_rxOkCallback(packet); } } - // Search for the demodulator that was locked on this event to free it. + // Search for the demodulator that was locked on this event to free it. - std::list>::iterator it; + std::list>::iterator it; - for (it = m_receptionPaths.begin (); it != m_receptionPaths.end (); ++it) + for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it) { - Ptr currentPath = *it; + Ptr currentPath = *it; - if (currentPath->GetEvent () == event) + if (currentPath->GetEvent() == event) { - currentPath->Free (); - m_occupiedReceptionPaths--; - return; + currentPath->Free(); + m_occupiedReceptionPaths--; + return; } } } diff --git a/model/simple-gateway-lora-phy.h b/model/simple-gateway-lora-phy.h index 53c98b97bd..ef628cd1de 100644 --- a/model/simple-gateway-lora-phy.h +++ b/model/simple-gateway-lora-phy.h @@ -21,17 +21,21 @@ #ifndef SIMPLE_GATEWAY_LORA_PHY_H #define SIMPLE_GATEWAY_LORA_PHY_H -#include "ns3/object.h" -#include "ns3/net-device.h" -#include "ns3/nstime.h" +#include "gateway-lora-phy.h" + #include "ns3/mobility-model.h" +#include "ns3/net-device.h" #include "ns3/node.h" -#include "ns3/gateway-lora-phy.h" +#include "ns3/nstime.h" +#include "ns3/object.h" #include "ns3/traced-value.h" + #include -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LoraChannel; @@ -40,25 +44,29 @@ class LoraChannel; */ class SimpleGatewayLoraPhy : public GatewayLoraPhy { -public: - static TypeId GetTypeId (void); + public: + static TypeId GetTypeId(void); - SimpleGatewayLoraPhy (); - virtual ~SimpleGatewayLoraPhy (); + SimpleGatewayLoraPhy(); + virtual ~SimpleGatewayLoraPhy(); - virtual void StartReceive (Ptr packet, double rxPowerDbm, uint8_t sf, - Time duration, double frequencyMHz); + virtual void StartReceive(Ptr packet, + double rxPowerDbm, + uint8_t sf, + Time duration, + double frequencyMHz); - virtual void EndReceive (Ptr packet, - Ptr event); + virtual void EndReceive(Ptr packet, Ptr event); - virtual void Send (Ptr packet, LoraTxParameters txParams, - double frequencyMHz, double txPowerDbm); + virtual void Send(Ptr packet, + LoraTxParameters txParams, + double frequencyMHz, + double txPowerDbm); -private: + private: }; -} /* namespace ns3 */ +} // namespace lorawan -} +} // namespace ns3 #endif /* SIMPLE_GATEWAY_LORA_PHY_H */ diff --git a/model/sub-band.cc b/model/sub-band.cc index e08c7298df..c2282c4801 100644 --- a/model/sub-band.cc +++ b/model/sub-band.cc @@ -18,94 +18,96 @@ * Author: Davide Magrin */ -#include "ns3/sub-band.h" +#include "sub-band.h" + #include "ns3/log.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ -NS_LOG_COMPONENT_DEFINE ("SubBand"); +NS_LOG_COMPONENT_DEFINE("SubBand"); -NS_OBJECT_ENSURE_REGISTERED (SubBand); +NS_OBJECT_ENSURE_REGISTERED(SubBand); TypeId -SubBand::GetTypeId (void) +SubBand::GetTypeId(void) +{ + static TypeId tid = TypeId("ns3::SubBand").SetParent().SetGroupName("lorawan"); + return tid; +} + +SubBand::SubBand() +{ + NS_LOG_FUNCTION(this); +} + +SubBand::SubBand(double firstFrequency, + double lastFrequency, + double dutyCycle, + double maxTxPowerDbm) + : m_firstFrequency(firstFrequency), + m_lastFrequency(lastFrequency), + m_dutyCycle(dutyCycle), + m_nextTransmissionTime(Seconds(0)), + m_maxTxPowerDbm(maxTxPowerDbm) { - static TypeId tid = TypeId ("ns3::SubBand") - .SetParent () - .SetGroupName ("lorawan"); - return tid; + NS_LOG_FUNCTION(this << firstFrequency << lastFrequency << dutyCycle << maxTxPowerDbm); } -SubBand::SubBand () +SubBand::~SubBand() { - NS_LOG_FUNCTION (this); + NS_LOG_FUNCTION(this); } - SubBand::SubBand (double firstFrequency, double lastFrequency, double dutyCycle, - double maxTxPowerDbm) : - m_firstFrequency (firstFrequency), - m_lastFrequency (lastFrequency), - m_dutyCycle (dutyCycle), - m_nextTransmissionTime (Seconds (0)), - m_maxTxPowerDbm (maxTxPowerDbm) - { - NS_LOG_FUNCTION (this << firstFrequency << lastFrequency << dutyCycle << - maxTxPowerDbm); - } - - SubBand::~SubBand () - { - NS_LOG_FUNCTION (this); - } - - double - SubBand::GetFirstFrequency (void) - { +double +SubBand::GetFirstFrequency(void) +{ return m_firstFrequency; - } +} - double - SubBand::GetDutyCycle (void) - { +double +SubBand::GetDutyCycle(void) +{ return m_dutyCycle; - } +} - bool - SubBand::BelongsToSubBand (double frequency) - { +bool +SubBand::BelongsToSubBand(double frequency) +{ return (frequency > m_firstFrequency) && (frequency < m_lastFrequency); - } - - bool - SubBand::BelongsToSubBand (Ptr logicalChannel) - { - double frequency = logicalChannel->GetFrequency (); - return BelongsToSubBand (frequency); - } - - void - SubBand::SetNextTransmissionTime (Time nextTime) - { +} + +bool +SubBand::BelongsToSubBand(Ptr logicalChannel) +{ + double frequency = logicalChannel->GetFrequency(); + return BelongsToSubBand(frequency); +} + +void +SubBand::SetNextTransmissionTime(Time nextTime) +{ m_nextTransmissionTime = nextTime; - } +} - Time - SubBand::GetNextTransmissionTime (void) - { +Time +SubBand::GetNextTransmissionTime(void) +{ return m_nextTransmissionTime; - } +} - void - SubBand::SetMaxTxPowerDbm (double maxTxPowerDbm) - { +void +SubBand::SetMaxTxPowerDbm(double maxTxPowerDbm) +{ m_maxTxPowerDbm = maxTxPowerDbm; - } +} - double - SubBand::GetMaxTxPowerDbm (void) - { +double +SubBand::GetMaxTxPowerDbm(void) +{ return m_maxTxPowerDbm; - } -} } +} // namespace lorawan +} // namespace ns3 diff --git a/model/sub-band.h b/model/sub-band.h index 47e6d604f3..cd9ba5ed22 100644 --- a/model/sub-band.h +++ b/model/sub-band.h @@ -21,12 +21,15 @@ #ifndef SUB_BAND_H #define SUB_BAND_H -#include "ns3/object.h" -#include "ns3/logical-lora-channel.h" +#include "logical-lora-channel.h" + #include "ns3/nstime.h" +#include "ns3/object.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ class LogicalLoraChannel; @@ -36,104 +39,104 @@ class LogicalLoraChannel; */ class SubBand : public Object { -public: - static TypeId GetTypeId (void); - - SubBand (); - - /** - * Create a new SubBand by specifying all of its properties. - * - * \param firstFrequency The SubBand's lowest frequency. - * \param lastFrequency The SubBand's highest frequency. - * \param dutyCycle The duty cycle (as a fraction) allowed on this SubBand. - * \param maxTxPowerDbm The maximum transmission power [dBm] allowed on this SubBand. - */ - SubBand (double firstFrequency, double lastFrequency, double dutyCycle, double maxTxPowerDbm); - - virtual ~SubBand (); - - /** - * Get the lowest frequency of the SubBand. - * - * \return The lowest frequency of the SubBand. - */ - double GetFirstFrequency (void); - - /** - * Get the last frequency of the subband. - * - * \return The lowest frequency of the SubBand. - */ - // double GetLastFrequency (void); - - /** - * Get the duty cycle of the subband. - * - * \return The duty cycle (as a fraction) that needs to be enforced on this - * SubBand. - */ - double GetDutyCycle (void); - - /** - * Update the next transmission time. - * - * This function is used by LogicalLoraChannelHelper, which computes the time - * based on the SubBand's duty cycle and on the transmission duration. - * - * \param nextTime The future time from which transmission should be allowed - * again. - */ - void SetNextTransmissionTime (Time nextTime); - - /** - * Returns the next time from which transmission on this subband will be - * possible. - * - * \return The next time at which transmission in this SubBand will be - * allowed. - */ - Time GetNextTransmissionTime (void); - - /** - * Return whether or not a frequency belongs to this SubBand. - * - * \param frequency the frequency we want to test against the current subband - * \return True if the frequency is between firstFrequency and lastFrequency, - * false otherwise. - */ - bool BelongsToSubBand (double frequency); - - /** - * Return whether or not a channel belongs to this SubBand. - * - * \param channel the channel we want to test against the current subband - * \return True if the channel's center frequency is between firstFrequency - * and lastFrequency, false otherwise. - */ - bool BelongsToSubBand (Ptr channel); - - /** - * Set the maximum transmission power that is allowed on this SubBand. - * - * \param maxTxPowerDbm The maximum transmission power [dBm] to set. - */ - void SetMaxTxPowerDbm (double maxTxPowerDbm); - - /** - * Return the maximum transmission power that is allowed on this SubBand - * - * \return The maximum transmission power, in dBm. - */ - double GetMaxTxPowerDbm (void); - -private: - double m_firstFrequency; //!< Starting frequency of the subband, in MHz - double m_lastFrequency; //!< Ending frequency of the subband, in MHz - double m_dutyCycle; //!< The duty cycle that needs to be enforced on this subband - Time m_nextTransmissionTime; //!< The next time a transmission will be allowed in this subband - double m_maxTxPowerDbm; //!< The maximum transmission power that is admitted on this subband + public: + static TypeId GetTypeId(void); + + SubBand(); + + /** + * Create a new SubBand by specifying all of its properties. + * + * \param firstFrequency The SubBand's lowest frequency. + * \param lastFrequency The SubBand's highest frequency. + * \param dutyCycle The duty cycle (as a fraction) allowed on this SubBand. + * \param maxTxPowerDbm The maximum transmission power [dBm] allowed on this SubBand. + */ + SubBand(double firstFrequency, double lastFrequency, double dutyCycle, double maxTxPowerDbm); + + virtual ~SubBand(); + + /** + * Get the lowest frequency of the SubBand. + * + * \return The lowest frequency of the SubBand. + */ + double GetFirstFrequency(void); + + /** + * Get the last frequency of the subband. + * + * \return The lowest frequency of the SubBand. + */ + // double GetLastFrequency (void); + + /** + * Get the duty cycle of the subband. + * + * \return The duty cycle (as a fraction) that needs to be enforced on this + * SubBand. + */ + double GetDutyCycle(void); + + /** + * Update the next transmission time. + * + * This function is used by LogicalLoraChannelHelper, which computes the time + * based on the SubBand's duty cycle and on the transmission duration. + * + * \param nextTime The future time from which transmission should be allowed + * again. + */ + void SetNextTransmissionTime(Time nextTime); + + /** + * Returns the next time from which transmission on this subband will be + * possible. + * + * \return The next time at which transmission in this SubBand will be + * allowed. + */ + Time GetNextTransmissionTime(void); + + /** + * Return whether or not a frequency belongs to this SubBand. + * + * \param frequency the frequency we want to test against the current subband + * \return True if the frequency is between firstFrequency and lastFrequency, + * false otherwise. + */ + bool BelongsToSubBand(double frequency); + + /** + * Return whether or not a channel belongs to this SubBand. + * + * \param channel the channel we want to test against the current subband + * \return True if the channel's center frequency is between firstFrequency + * and lastFrequency, false otherwise. + */ + bool BelongsToSubBand(Ptr channel); + + /** + * Set the maximum transmission power that is allowed on this SubBand. + * + * \param maxTxPowerDbm The maximum transmission power [dBm] to set. + */ + void SetMaxTxPowerDbm(double maxTxPowerDbm); + + /** + * Return the maximum transmission power that is allowed on this SubBand + * + * \return The maximum transmission power, in dBm. + */ + double GetMaxTxPowerDbm(void); + + private: + double m_firstFrequency; //!< Starting frequency of the subband, in MHz + double m_lastFrequency; //!< Ending frequency of the subband, in MHz + double m_dutyCycle; //!< The duty cycle that needs to be enforced on this subband + Time m_nextTransmissionTime; //!< The next time a transmission will be allowed in this subband + double m_maxTxPowerDbm; //!< The maximum transmission power that is admitted on this subband }; -} /* namespace ns3 */ -} +} // namespace lorawan +} // namespace ns3 #endif /* SUB_BAND_H */ diff --git a/test/lorawan-test-suite.cc b/test/lorawan-test-suite.cc index 747785a2bb..f893ca1518 100644 --- a/test/lorawan-test-suite.cc +++ b/test/lorawan-test-suite.cc @@ -1,13 +1,13 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ // Include headers of classes to test +#include "ns3/constant-position-mobility-model.h" #include "ns3/log.h" #include "ns3/lora-helper.h" -#include "ns3/simple-end-device-lora-phy.h" -#include "ns3/simple-gateway-lora-phy.h" #include "ns3/mobility-helper.h" #include "ns3/one-shot-sender-helper.h" -#include "ns3/constant-position-mobility-model.h" +#include "ns3/simple-end-device-lora-phy.h" +#include "ns3/simple-gateway-lora-phy.h" // An essential include is test.h #include "ns3/test.h" @@ -15,7 +15,7 @@ using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("LorawanTestSuite"); +NS_LOG_COMPONENT_DEFINE("LorawanTestSuite"); /******************** * InterferenceTest * @@ -23,147 +23,160 @@ NS_LOG_COMPONENT_DEFINE ("LorawanTestSuite"); class InterferenceTest : public TestCase { -public: - InterferenceTest (); - virtual ~InterferenceTest (); + public: + InterferenceTest(); + virtual ~InterferenceTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -InterferenceTest::InterferenceTest () - : TestCase ("Verify that LoraInterferenceHelper works as expected") +InterferenceTest::InterferenceTest() + : TestCase("Verify that LoraInterferenceHelper works as expected") { } // Reminder that the test case should clean up after itself -InterferenceTest::~InterferenceTest () +InterferenceTest::~InterferenceTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -InterferenceTest::DoRun (void) +InterferenceTest::DoRun(void) { - NS_LOG_DEBUG ("InterferenceTest"); - - LoraInterferenceHelper interferenceHelper; - - double frequency = 868.1; - double differentFrequency = 868.3; - - Ptr event; - Ptr event1; - - // Test overlap duration - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - event1 = interferenceHelper.Add (Seconds (1), 14, 12, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.GetOverlapTime (event, event1), Seconds (1), - "Overlap computation didn't give the expected result"); - interferenceHelper.ClearAllEvents (); - - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - event1 = interferenceHelper.Add (Seconds (1.5), 14, 12, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.GetOverlapTime (event, event1), Seconds (1.5), - "Overlap computation didn't give the expected result"); - interferenceHelper.ClearAllEvents (); - - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - event1 = interferenceHelper.Add (Seconds (3), 14, 12, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.GetOverlapTime (event, event1), Seconds (2), - "Overlap computation didn't give the expected result"); - interferenceHelper.ClearAllEvents (); - - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - event1 = interferenceHelper.Add (Seconds (2), 14, 12, 0, frequency); - // Because of some strange behavior, this test would get stuck if we used the same syntax of the previous ones. - // This works instead. - bool retval = interferenceHelper.GetOverlapTime (event, event1) == Seconds (2); - NS_TEST_EXPECT_MSG_EQ (retval, true, "Overlap computation didn't give the expected result"); - interferenceHelper.ClearAllEvents (); - - // Perfect overlap, packet survives - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14, 12, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Perfect overlap, packet survives - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 - 7, 7, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Perfect overlap, packet destroyed - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 - 6, 7, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 7, - "Packet was not destroyed by interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Partial overlap, packet survives - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (1), 14 - 6, 7, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Different frequencys - // Packet would be destroyed if they were on the same frequency, but survives - // since they are on different frequencies - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14, 7, 0, differentFrequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Different SFs - // Packet would be destroyed if they both were SF7, but survives thanks to SF - // orthogonality - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 8, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); - - // SF imperfect orthogonality - // Different SFs are orthogonal only up to a point - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 17, 8, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 8, - "Packet was not destroyed by interference as expected"); - interferenceHelper.ClearAllEvents (); - - // If a more 'distant' SF is used, isolation gets better - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 17, 10, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet was destroyed by interference while it should have survived"); - interferenceHelper.ClearAllEvents (); - - // Cumulative interference - // Same-SF interference is cumulative - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 8, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 8, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 8, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 8, - "Packet was not destroyed by interference as expected"); - interferenceHelper.ClearAllEvents (); - - // Cumulative interference - // Interference is not cumulative between different SFs - event = interferenceHelper.Add (Seconds (2), 14, 7, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 8, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 9, 0, frequency); - interferenceHelper.Add (Seconds (2), 14 + 16, 10, 0, frequency); - NS_TEST_EXPECT_MSG_EQ (interferenceHelper.IsDestroyedByInterference (event), 0, - "Packet did not survive interference as expected"); - interferenceHelper.ClearAllEvents (); + NS_LOG_DEBUG("InterferenceTest"); + + LoraInterferenceHelper interferenceHelper; + + double frequency = 868.1; + double differentFrequency = 868.3; + + Ptr event; + Ptr event1; + + // Test overlap duration + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + event1 = interferenceHelper.Add(Seconds(1), 14, 12, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.GetOverlapTime(event, event1), + Seconds(1), + "Overlap computation didn't give the expected result"); + interferenceHelper.ClearAllEvents(); + + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + event1 = interferenceHelper.Add(Seconds(1.5), 14, 12, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.GetOverlapTime(event, event1), + Seconds(1.5), + "Overlap computation didn't give the expected result"); + interferenceHelper.ClearAllEvents(); + + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + event1 = interferenceHelper.Add(Seconds(3), 14, 12, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.GetOverlapTime(event, event1), + Seconds(2), + "Overlap computation didn't give the expected result"); + interferenceHelper.ClearAllEvents(); + + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + event1 = interferenceHelper.Add(Seconds(2), 14, 12, 0, frequency); + // Because of some strange behavior, this test would get stuck if we used the same syntax of the + // previous ones. This works instead. + bool retval = interferenceHelper.GetOverlapTime(event, event1) == Seconds(2); + NS_TEST_EXPECT_MSG_EQ(retval, true, "Overlap computation didn't give the expected result"); + interferenceHelper.ClearAllEvents(); + + // Perfect overlap, packet survives + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14, 12, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Perfect overlap, packet survives + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 - 7, 7, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Perfect overlap, packet destroyed + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 - 6, 7, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 7, + "Packet was not destroyed by interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Partial overlap, packet survives + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(1), 14 - 6, 7, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Different frequencys + // Packet would be destroyed if they were on the same frequency, but survives + // since they are on different frequencies + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14, 7, 0, differentFrequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Different SFs + // Packet would be destroyed if they both were SF7, but survives thanks to SF + // orthogonality + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 8, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); + + // SF imperfect orthogonality + // Different SFs are orthogonal only up to a point + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 17, 8, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 8, + "Packet was not destroyed by interference as expected"); + interferenceHelper.ClearAllEvents(); + + // If a more 'distant' SF is used, isolation gets better + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 17, 10, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet was destroyed by interference while it should have survived"); + interferenceHelper.ClearAllEvents(); + + // Cumulative interference + // Same-SF interference is cumulative + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 8, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 8, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 8, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 8, + "Packet was not destroyed by interference as expected"); + interferenceHelper.ClearAllEvents(); + + // Cumulative interference + // Interference is not cumulative between different SFs + event = interferenceHelper.Add(Seconds(2), 14, 7, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 8, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 9, 0, frequency); + interferenceHelper.Add(Seconds(2), 14 + 16, 10, 0, frequency); + NS_TEST_EXPECT_MSG_EQ(interferenceHelper.IsDestroyedByInterference(event), + 0, + "Packet did not survive interference as expected"); + interferenceHelper.ClearAllEvents(); } /*************** @@ -172,75 +185,80 @@ InterferenceTest::DoRun (void) class AddressTest : public TestCase { -public: - AddressTest (); - virtual ~AddressTest (); + public: + AddressTest(); + virtual ~AddressTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -AddressTest::AddressTest () : TestCase ("Verify that LoraDeviceAddress works as expected") +AddressTest::AddressTest() + : TestCase("Verify that LoraDeviceAddress works as expected") { } // Reminder that the test case should clean up after itself -AddressTest::~AddressTest () +AddressTest::~AddressTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -AddressTest::DoRun (void) +AddressTest::DoRun(void) { - NS_LOG_DEBUG ("AddressTest"); - - ////////////////////////////////////// - // Test the LoraDeviceAddress class // - ////////////////////////////////////// - - // Address equality - LoraDeviceAddress firstAddress (0xFFFFFFFF); - LoraDeviceAddress secondAddress (0xFFFFFFFF); - NS_TEST_EXPECT_MSG_EQ ((firstAddress == secondAddress), true, "Addresses don't match"); - - // Address ordering - LoraDeviceAddress bigAddress (0xFFFFFF00); - LoraDeviceAddress smallAddress (0xFFF00000); - NS_TEST_EXPECT_MSG_EQ ((bigAddress > smallAddress), true, - "> function for addresses doesn't work correctly"); - - // Setting and getting - LoraDeviceAddress referenceAddress (0xFFFFFFFF); - LoraDeviceAddress address (0x00000000); - NS_TEST_EXPECT_MSG_EQ ((address != referenceAddress), true, "Different addresses match!"); - address.SetNwkAddr (0xFFFFFFF); - address.SetNwkID (0b1111111); - NS_TEST_EXPECT_MSG_EQ ((address == referenceAddress), true, - "Addresses set to be equal don't match"); - - // Serialization and deserialization - uint8_t buffer[4]; - LoraDeviceAddress toSerialize (0x0F0F0F0F); - toSerialize.Serialize (buffer); - LoraDeviceAddress deserialized = LoraDeviceAddress::Deserialize (buffer); - NS_TEST_EXPECT_MSG_EQ ((toSerialize == deserialized), true, - "Serialization + Deserialization doesn't yield an equal address"); - - /////////////////////////////////// - // Test the address generator class - /////////////////////////////////// - - LoraDeviceAddressGenerator addressGenerator; - for (int i = 0; i < 200; i++) + NS_LOG_DEBUG("AddressTest"); + + ////////////////////////////////////// + // Test the LoraDeviceAddress class // + ////////////////////////////////////// + + // Address equality + LoraDeviceAddress firstAddress(0xFFFFFFFF); + LoraDeviceAddress secondAddress(0xFFFFFFFF); + NS_TEST_EXPECT_MSG_EQ((firstAddress == secondAddress), true, "Addresses don't match"); + + // Address ordering + LoraDeviceAddress bigAddress(0xFFFFFF00); + LoraDeviceAddress smallAddress(0xFFF00000); + NS_TEST_EXPECT_MSG_EQ((bigAddress > smallAddress), + true, + "> function for addresses doesn't work correctly"); + + // Setting and getting + LoraDeviceAddress referenceAddress(0xFFFFFFFF); + LoraDeviceAddress address(0x00000000); + NS_TEST_EXPECT_MSG_EQ((address != referenceAddress), true, "Different addresses match!"); + address.SetNwkAddr(0xFFFFFFF); + address.SetNwkID(0b1111111); + NS_TEST_EXPECT_MSG_EQ((address == referenceAddress), + true, + "Addresses set to be equal don't match"); + + // Serialization and deserialization + uint8_t buffer[4]; + LoraDeviceAddress toSerialize(0x0F0F0F0F); + toSerialize.Serialize(buffer); + LoraDeviceAddress deserialized = LoraDeviceAddress::Deserialize(buffer); + NS_TEST_EXPECT_MSG_EQ((toSerialize == deserialized), + true, + "Serialization + Deserialization doesn't yield an equal address"); + + /////////////////////////////////// + // Test the address generator class + /////////////////////////////////// + + LoraDeviceAddressGenerator addressGenerator; + for (int i = 0; i < 200; i++) { - addressGenerator.NextAddress (); + addressGenerator.NextAddress(); } - // After 200 iterations, the address should be 0xC9 - NS_TEST_EXPECT_MSG_EQ ((addressGenerator.GetNextAddress () == LoraDeviceAddress (0xC9)), true, - "LoraDeviceAddressGenerator doesn't increment as expected"); + // After 200 iterations, the address should be 0xC9 + NS_TEST_EXPECT_MSG_EQ((addressGenerator.GetNextAddress() == LoraDeviceAddress(0xC9)), + true, + "LoraDeviceAddressGenerator doesn't increment as expected"); } /*************** @@ -249,132 +267,149 @@ AddressTest::DoRun (void) class HeaderTest : public TestCase { -public: - HeaderTest (); - virtual ~HeaderTest (); + public: + HeaderTest(); + virtual ~HeaderTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -HeaderTest::HeaderTest () - : TestCase ("Verify that LorawanMacHeader and LoraFrameHeader work as expected") +HeaderTest::HeaderTest() + : TestCase("Verify that LorawanMacHeader and LoraFrameHeader work as expected") { } // Reminder that the test case should clean up after itself -HeaderTest::~HeaderTest () +HeaderTest::~HeaderTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -HeaderTest::DoRun (void) +HeaderTest::DoRun(void) { - NS_LOG_DEBUG ("HeaderTest"); - - ////////////////////////////////// - // Test the LorawanMacHeader class // - ////////////////////////////////// - LorawanMacHeader macHdr; - macHdr.SetMType (LorawanMacHeader::CONFIRMED_DATA_DOWN); - macHdr.SetMajor (1); - - Buffer macBuf; - macBuf.AddAtStart (100); - Buffer::Iterator macSerialized = macBuf.Begin (); - macHdr.Serialize (macSerialized); - - macHdr.Deserialize (macSerialized); - - NS_TEST_EXPECT_MSG_EQ ((macHdr.GetMType () == LorawanMacHeader::CONFIRMED_DATA_DOWN), true, - "MType changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ ((macHdr.GetMajor () == 1), true, - "MType changes in the serialization/deserialization process"); - - //////////////////////////////////// - // Test the LoraFrameHeader class // - //////////////////////////////////// - LoraFrameHeader frameHdr; - frameHdr.SetAsDownlink (); - frameHdr.SetAck (true); - frameHdr.SetAdr (false); - frameHdr.SetFCnt (1); - frameHdr.SetAddress (LoraDeviceAddress (56, 1864)); - frameHdr.AddLinkCheckAns (10, 1); - - // Serialization - Buffer buf; - buf.AddAtStart (100); - Buffer::Iterator serialized = buf.Begin (); - frameHdr.Serialize (serialized); - - // Deserialization - frameHdr.Deserialize (serialized); - - Ptr command = (*(frameHdr.GetCommands ().begin ()))->GetObject (); - uint8_t margin = command->GetMargin (); - uint8_t gwCnt = command->GetGwCnt (); - - NS_TEST_EXPECT_MSG_EQ (frameHdr.GetAck (), true, - "Ack changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ (frameHdr.GetAdr (), false, - "Adr changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ (frameHdr.GetFCnt (), 1, - "FCnt changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ ((frameHdr.GetAddress () == LoraDeviceAddress (56, 1864)), true, - "Address changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ (margin, 10, "Margin changes in the serialization/deserialization process"); - NS_TEST_EXPECT_MSG_EQ (gwCnt, 1, "GwCnt changes in the serialization/deserialization process"); - - ///////////////////////////////////////////////// - // Test a combination of the two above classes // - ///////////////////////////////////////////////// - Ptr pkt = Create (10); - pkt->AddHeader (frameHdr); - pkt->AddHeader (macHdr); - - // Length = Payload + FrameHeader + MacHeader - // = 10 + (8+3) + 1 = 22 - NS_TEST_EXPECT_MSG_EQ ((pkt->GetSize ()), 22, "Wrong size of packet + headers"); - - LorawanMacHeader macHdr1; - - pkt->RemoveHeader (macHdr1); - - NS_TEST_EXPECT_MSG_EQ ((pkt->GetSize ()), 21, "Wrong size of packet + headers - macHeader"); - - LoraFrameHeader frameHdr1; - frameHdr1.SetAsDownlink (); - - pkt->RemoveHeader (frameHdr1); - Ptr linkCheckAns = - (*(frameHdr1.GetCommands ().begin ()))->GetObject (); - - NS_TEST_EXPECT_MSG_EQ ((pkt->GetSize ()), 10, - "Wrong size of packet + headers - macHeader - frameHeader"); - - // Verify contents of removed MAC header - NS_TEST_EXPECT_MSG_EQ (macHdr1.GetMType (), macHdr.GetMType (), - "Removed header contents don't match"); - NS_TEST_EXPECT_MSG_EQ (macHdr1.GetMajor (), macHdr.GetMajor (), - "Removed header contents don't match"); - - // Verify contents of removed frame header - NS_TEST_EXPECT_MSG_EQ (frameHdr1.GetAck (), frameHdr.GetAck (), - "Removed header contents don't match"); - NS_TEST_EXPECT_MSG_EQ (frameHdr1.GetAdr (), frameHdr.GetAdr (), - "Removed header contents don't match"); - NS_TEST_EXPECT_MSG_EQ (frameHdr1.GetFCnt (), frameHdr.GetFCnt (), - "Removed header contents don't match"); - NS_TEST_EXPECT_MSG_EQ ((frameHdr1.GetAddress () == frameHdr.GetAddress ()), true, - "Removed header contents don't match"); - NS_TEST_EXPECT_MSG_EQ (linkCheckAns->GetMargin (), 10, - "Removed header's MAC command contents don't match"); - NS_TEST_EXPECT_MSG_EQ (linkCheckAns->GetGwCnt (), 1, - "Removed header's MAC command contents don't match"); + NS_LOG_DEBUG("HeaderTest"); + + ////////////////////////////////// + // Test the LorawanMacHeader class // + ////////////////////////////////// + LorawanMacHeader macHdr; + macHdr.SetMType(LorawanMacHeader::CONFIRMED_DATA_DOWN); + macHdr.SetMajor(1); + + Buffer macBuf; + macBuf.AddAtStart(100); + Buffer::Iterator macSerialized = macBuf.Begin(); + macHdr.Serialize(macSerialized); + + macHdr.Deserialize(macSerialized); + + NS_TEST_EXPECT_MSG_EQ((macHdr.GetMType() == LorawanMacHeader::CONFIRMED_DATA_DOWN), + true, + "MType changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ((macHdr.GetMajor() == 1), + true, + "MType changes in the serialization/deserialization process"); + + //////////////////////////////////// + // Test the LoraFrameHeader class // + //////////////////////////////////// + LoraFrameHeader frameHdr; + frameHdr.SetAsDownlink(); + frameHdr.SetAck(true); + frameHdr.SetAdr(false); + frameHdr.SetFCnt(1); + frameHdr.SetAddress(LoraDeviceAddress(56, 1864)); + frameHdr.AddLinkCheckAns(10, 1); + + // Serialization + Buffer buf; + buf.AddAtStart(100); + Buffer::Iterator serialized = buf.Begin(); + frameHdr.Serialize(serialized); + + // Deserialization + frameHdr.Deserialize(serialized); + + Ptr command = (*(frameHdr.GetCommands().begin()))->GetObject(); + uint8_t margin = command->GetMargin(); + uint8_t gwCnt = command->GetGwCnt(); + + NS_TEST_EXPECT_MSG_EQ(frameHdr.GetAck(), + true, + "Ack changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ(frameHdr.GetAdr(), + false, + "Adr changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ(frameHdr.GetFCnt(), + 1, + "FCnt changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ((frameHdr.GetAddress() == LoraDeviceAddress(56, 1864)), + true, + "Address changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ(margin, + 10, + "Margin changes in the serialization/deserialization process"); + NS_TEST_EXPECT_MSG_EQ(gwCnt, 1, "GwCnt changes in the serialization/deserialization process"); + + ///////////////////////////////////////////////// + // Test a combination of the two above classes // + ///////////////////////////////////////////////// + Ptr pkt = Create(10); + pkt->AddHeader(frameHdr); + pkt->AddHeader(macHdr); + + // Length = Payload + FrameHeader + MacHeader + // = 10 + (8+3) + 1 = 22 + NS_TEST_EXPECT_MSG_EQ((pkt->GetSize()), 22, "Wrong size of packet + headers"); + + LorawanMacHeader macHdr1; + + pkt->RemoveHeader(macHdr1); + + NS_TEST_EXPECT_MSG_EQ((pkt->GetSize()), 21, "Wrong size of packet + headers - macHeader"); + + LoraFrameHeader frameHdr1; + frameHdr1.SetAsDownlink(); + + pkt->RemoveHeader(frameHdr1); + Ptr linkCheckAns = + (*(frameHdr1.GetCommands().begin()))->GetObject(); + + NS_TEST_EXPECT_MSG_EQ((pkt->GetSize()), + 10, + "Wrong size of packet + headers - macHeader - frameHeader"); + + // Verify contents of removed MAC header + NS_TEST_EXPECT_MSG_EQ(macHdr1.GetMType(), + macHdr.GetMType(), + "Removed header contents don't match"); + NS_TEST_EXPECT_MSG_EQ(macHdr1.GetMajor(), + macHdr.GetMajor(), + "Removed header contents don't match"); + + // Verify contents of removed frame header + NS_TEST_EXPECT_MSG_EQ(frameHdr1.GetAck(), + frameHdr.GetAck(), + "Removed header contents don't match"); + NS_TEST_EXPECT_MSG_EQ(frameHdr1.GetAdr(), + frameHdr.GetAdr(), + "Removed header contents don't match"); + NS_TEST_EXPECT_MSG_EQ(frameHdr1.GetFCnt(), + frameHdr.GetFCnt(), + "Removed header contents don't match"); + NS_TEST_EXPECT_MSG_EQ((frameHdr1.GetAddress() == frameHdr.GetAddress()), + true, + "Removed header contents don't match"); + NS_TEST_EXPECT_MSG_EQ(linkCheckAns->GetMargin(), + 10, + "Removed header's MAC command contents don't match"); + NS_TEST_EXPECT_MSG_EQ(linkCheckAns->GetGwCnt(), + 1, + "Removed header's MAC command contents don't match"); } /******************* @@ -383,355 +418,401 @@ HeaderTest::DoRun (void) class ReceivePathTest : public TestCase { -public: - ReceivePathTest (); - virtual ~ReceivePathTest (); - -private: - virtual void DoRun (void); - void Reset (void); - void OccupiedReceptionPaths (int oldValue, int newValue); - void NoMoreDemodulators (Ptr packet, uint32_t node); - void Interference (Ptr packet, uint32_t node); - void ReceivedPacket (Ptr packet, uint32_t node); - - Ptr gatewayPhy; - int m_noMoreDemodulatorsCalls = 0; - int m_interferenceCalls = 0; - int m_receivedPacketCalls = 0; - int m_maxOccupiedReceptionPaths = 0; + public: + ReceivePathTest(); + virtual ~ReceivePathTest(); + + private: + virtual void DoRun(void); + void Reset(void); + void OccupiedReceptionPaths(int oldValue, int newValue); + void NoMoreDemodulators(Ptr packet, uint32_t node); + void Interference(Ptr packet, uint32_t node); + void ReceivedPacket(Ptr packet, uint32_t node); + + Ptr gatewayPhy; + int m_noMoreDemodulatorsCalls = 0; + int m_interferenceCalls = 0; + int m_receivedPacketCalls = 0; + int m_maxOccupiedReceptionPaths = 0; }; // Add some help text to this case to describe what it is intended to test -ReceivePathTest::ReceivePathTest () : TestCase ("Verify that ReceivePaths work as expected") +ReceivePathTest::ReceivePathTest() + : TestCase("Verify that ReceivePaths work as expected") { } // Reminder that the test case should clean up after itself -ReceivePathTest::~ReceivePathTest () +ReceivePathTest::~ReceivePathTest() { } void -ReceivePathTest::Reset (void) +ReceivePathTest::Reset(void) { - // FIXME - // m_noMoreDemodulatorsCalls = 0; - // m_interferenceCalls = 0; - // m_receivedPacketCalls = 0; - // m_maxOccupiedReceptionPaths = 0; - - // gatewayPhy = CreateObject (); - // gatewayPhy->TraceConnectWithoutContext ( - // "LostPacketBecauseNoMoreReceivers", - // MakeCallback (&ReceivePathTest::NoMoreDemodulators, this)); - // gatewayPhy->TraceConnectWithoutContext ("LostPacketBecauseInterference", - // MakeCallback (&ReceivePathTest::Interference, this)); - // gatewayPhy->TraceConnectWithoutContext ("ReceivedPacket", - // MakeCallback (&ReceivePathTest::ReceivedPacket, this)); - // gatewayPhy->TraceConnectWithoutContext ( - // "OccupiedReceptionPaths", MakeCallback (&ReceivePathTest::OccupiedReceptionPaths, this)); - - // // Add receive paths - // gatewayPhy->AddReceptionPath (); - // gatewayPhy->AddReceptionPath (); - // gatewayPhy->AddReceptionPath (); - // gatewayPhy->AddReceptionPath (); - // gatewayPhy->AddReceptionPath (); - // gatewayPhy->AddReceptionPath (); + // FIXME + // m_noMoreDemodulatorsCalls = 0; + // m_interferenceCalls = 0; + // m_receivedPacketCalls = 0; + // m_maxOccupiedReceptionPaths = 0; + + // gatewayPhy = CreateObject (); + // gatewayPhy->TraceConnectWithoutContext ( + // "LostPacketBecauseNoMoreReceivers", + // MakeCallback (&ReceivePathTest::NoMoreDemodulators, this)); + // gatewayPhy->TraceConnectWithoutContext ("LostPacketBecauseInterference", + // MakeCallback (&ReceivePathTest::Interference, this)); + // gatewayPhy->TraceConnectWithoutContext ("ReceivedPacket", + // MakeCallback (&ReceivePathTest::ReceivedPacket, + // this)); + // gatewayPhy->TraceConnectWithoutContext ( + // "OccupiedReceptionPaths", MakeCallback (&ReceivePathTest::OccupiedReceptionPaths, this)); + + // // Add receive paths + // gatewayPhy->AddReceptionPath (); + // gatewayPhy->AddReceptionPath (); + // gatewayPhy->AddReceptionPath (); + // gatewayPhy->AddReceptionPath (); + // gatewayPhy->AddReceptionPath (); + // gatewayPhy->AddReceptionPath (); } void -ReceivePathTest::OccupiedReceptionPaths (int oldValue, int newValue) +ReceivePathTest::OccupiedReceptionPaths(int oldValue, int newValue) { - NS_LOG_FUNCTION (oldValue << newValue); + NS_LOG_FUNCTION(oldValue << newValue); - if (m_maxOccupiedReceptionPaths < newValue) + if (m_maxOccupiedReceptionPaths < newValue) { - m_maxOccupiedReceptionPaths = newValue; + m_maxOccupiedReceptionPaths = newValue; } } void -ReceivePathTest::NoMoreDemodulators (Ptr packet, uint32_t node) +ReceivePathTest::NoMoreDemodulators(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_noMoreDemodulatorsCalls++; + m_noMoreDemodulatorsCalls++; } void -ReceivePathTest::Interference (Ptr packet, uint32_t node) +ReceivePathTest::Interference(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_interferenceCalls++; + m_interferenceCalls++; } void -ReceivePathTest::ReceivedPacket (Ptr packet, uint32_t node) +ReceivePathTest::ReceivedPacket(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_receivedPacketCalls++; + m_receivedPacketCalls++; } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -ReceivePathTest::DoRun (void) +ReceivePathTest::DoRun(void) { - NS_LOG_DEBUG ("ReceivePathTest"); - - Ptr packet = Create (); - - Reset (); - - // FIXME - // ////////////////////////////////////////////////////////////////////////////////// - // // If no ReceptionPath is configured to listen on a frequency, no packet is received - // ////////////////////////////////////////////////////////////////////////////////// - - // Simulator::Schedule (Seconds (1), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (1), frequency4); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); - - // Reset (); - - // ////////////////////////////////////////////////////////////////////////////// - // // A ReceptionPath can receive a packet of any SF without any preconfiguration - // ////////////////////////////////////////////////////////////////////////////// - - // Simulator::Schedule (Seconds (1), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (1), frequency1); - // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (1), frequency1); - // Simulator::Schedule (Seconds (5), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (1), frequency1); - // Simulator::Schedule (Seconds (7), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (1), frequency1); - // Simulator::Schedule (Seconds (9), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 11, - // Seconds (1), frequency1); - // Simulator::Schedule (Seconds (11), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, - // 12, Seconds (1), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Schedule two reception events at the first frequency, where there are two - // // reception paths listening. Each packet should be received correctly. - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (4), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 2, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Interference between packets on the same frequency and different ReceptionPaths - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 2, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Three receptions where only two receivePaths are available - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Packets that are on different frequencys do not interfere - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency2); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Full capacity - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 11, - // Seconds (4), frequency3); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 12, - // Seconds (4), frequency3); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Full capacity + 1 - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 11, - // Seconds (4), frequency3); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 12, - // Seconds (4), frequency3); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (4), frequency3); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Receive Paths are correctly freed - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 11, - // Seconds (4), frequency3); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 12, - // Seconds (4), frequency3); - - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 9, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 10, - // Seconds (4), frequency2); - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 11, - // Seconds (4), frequency3); - // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 12, - // Seconds (4), frequency3); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 12, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Receive Paths stay occupied exactly for the necessary time - // // Occupy both ReceptionPaths centered at frequency1 - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 8, - // Seconds (4), frequency1); - - // // This packet will find no free ReceptionPaths - // Simulator::Schedule (Seconds (2 + 4) - NanoSeconds (1), &SimpleGatewayLoraPhy::StartReceive, - // gatewayPhy, packet, 14, 9, Seconds (4), frequency1); - - // // This packet will find a free ReceptionPath - // Simulator::Schedule (Seconds (2 + 4) + NanoSeconds (1), &SimpleGatewayLoraPhy::StartReceive, - // gatewayPhy, packet, 14, 10, Seconds (4), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 3, "Unexpected value"); - - // Reset (); - - // /////////////////////////////////////////////////////////////////////////// - // // Only one ReceivePath locks on the incoming packet - // /////////////////////////////////////////////////////////////////////////// - // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, 14, 7, - // Seconds (4), frequency1); - - // Simulator::Stop (Hours (2)); - // Simulator::Run (); - // Simulator::Destroy (); - - // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 1, "Unexpected value"); - // NS_TEST_EXPECT_MSG_EQ (m_maxOccupiedReceptionPaths, 1, "Unexpected value"); + NS_LOG_DEBUG("ReceivePathTest"); + + Ptr packet = Create(); + + Reset(); + + // FIXME + // ////////////////////////////////////////////////////////////////////////////////// + // // If no ReceptionPath is configured to listen on a frequency, no packet is received + // ////////////////////////////////////////////////////////////////////////////////// + + // Simulator::Schedule (Seconds (1), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (1), frequency4); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); + + // Reset (); + + // ////////////////////////////////////////////////////////////////////////////// + // // A ReceptionPath can receive a packet of any SF without any preconfiguration + // ////////////////////////////////////////////////////////////////////////////// + + // Simulator::Schedule (Seconds (1), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (1), frequency1); + // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (1), frequency1); + // Simulator::Schedule (Seconds (5), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (1), frequency1); + // Simulator::Schedule (Seconds (7), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (1), frequency1); + // Simulator::Schedule (Seconds (9), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 11, + // Seconds (1), frequency1); + // Simulator::Schedule (Seconds (11), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, + // 12, Seconds (1), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Schedule two reception events at the first frequency, where there are two + // // reception paths listening. Each packet should be received correctly. + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (4), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 2, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Interference between packets on the same frequency and different ReceptionPaths + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 2, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Three receptions where only two receivePaths are available + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (3), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Packets that are on different frequencys do not interfere + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency2); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Full capacity + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 11, + // Seconds (4), frequency3); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 12, + // Seconds (4), frequency3); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Full capacity + 1 + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 11, + // Seconds (4), frequency3); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 12, + // Seconds (4), frequency3); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (4), frequency3); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 6, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Receive Paths are correctly freed + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 11, + // Seconds (4), frequency3); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 12, + // Seconds (4), frequency3); + + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 9, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 10, + // Seconds (4), frequency2); + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 11, + // Seconds (4), frequency3); + // Simulator::Schedule (Seconds (8), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 12, + // Seconds (4), frequency3); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 12, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Receive Paths stay occupied exactly for the necessary time + // // Occupy both ReceptionPaths centered at frequency1 + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 8, + // Seconds (4), frequency1); + + // // This packet will find no free ReceptionPaths + // Simulator::Schedule (Seconds (2 + 4) - NanoSeconds (1), &SimpleGatewayLoraPhy::StartReceive, + // gatewayPhy, packet, 14, 9, Seconds (4), frequency1); + + // // This packet will find a free ReceptionPath + // Simulator::Schedule (Seconds (2 + 4) + NanoSeconds (1), &SimpleGatewayLoraPhy::StartReceive, + // gatewayPhy, packet, 14, 10, Seconds (4), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 1, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 3, "Unexpected value"); + + // Reset (); + + // /////////////////////////////////////////////////////////////////////////// + // // Only one ReceivePath locks on the incoming packet + // /////////////////////////////////////////////////////////////////////////// + // Simulator::Schedule (Seconds (2), &SimpleGatewayLoraPhy::StartReceive, gatewayPhy, packet, + // 14, 7, + // Seconds (4), frequency1); + + // Simulator::Stop (Hours (2)); + // Simulator::Run (); + // Simulator::Destroy (); + + // NS_TEST_EXPECT_MSG_EQ (m_noMoreDemodulatorsCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 0, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_receivedPacketCalls, 1, "Unexpected value"); + // NS_TEST_EXPECT_MSG_EQ (m_maxOccupiedReceptionPaths, 1, "Unexpected value"); } /************************** @@ -740,113 +821,121 @@ ReceivePathTest::DoRun (void) class LogicalLoraChannelTest : public TestCase { -public: - LogicalLoraChannelTest (); - virtual ~LogicalLoraChannelTest (); + public: + LogicalLoraChannelTest(); + virtual ~LogicalLoraChannelTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -LogicalLoraChannelTest::LogicalLoraChannelTest () - : TestCase ("Verify that LogicalLoraChannel and LogicalLoraChannelHelper work as expected") +LogicalLoraChannelTest::LogicalLoraChannelTest() + : TestCase("Verify that LogicalLoraChannel and LogicalLoraChannelHelper work as expected") { } // Reminder that the test case should clean up after itself -LogicalLoraChannelTest::~LogicalLoraChannelTest () +LogicalLoraChannelTest::~LogicalLoraChannelTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -LogicalLoraChannelTest::DoRun (void) +LogicalLoraChannelTest::DoRun(void) { - NS_LOG_DEBUG ("LogicalLoraChannelTest"); - - ///////////////////////////// - // Test LogicalLoraChannel // - ///////////////////////////// - - // Setup - Ptr channel1 = CreateObject (868); - Ptr channel2 = CreateObject (868); - Ptr channel3 = CreateObject (868.1); - Ptr channel4 = CreateObject (868.001); - - // Equality between channels - // Test the == and != operators - NS_TEST_EXPECT_MSG_EQ (channel1, channel2, "== operator doesn't work as expected"); - NS_TEST_EXPECT_MSG_NE (channel1, channel3, "!= operator doesn't work as expected"); - NS_TEST_EXPECT_MSG_NE (channel1, channel4, "!= operator doesn't work as expected"); - - ////////////////// - // Test SubBand // - ////////////////// - - // Setup - SubBand subBand (868, 868.7, 0.01, 14); - Ptr channel5 = CreateObject (870); - - // Test BelongsToSubBand - NS_TEST_EXPECT_MSG_EQ (subBand.BelongsToSubBand (channel3), true, - "BelongsToSubBand does not behave as expected"); - NS_TEST_EXPECT_MSG_EQ (subBand.BelongsToSubBand (channel3->GetFrequency ()), true, - "BelongsToSubBand does not behave as expected"); - NS_TEST_EXPECT_MSG_EQ (subBand.BelongsToSubBand (channel5), false, - "BelongsToSubBand does not behave as expected"); - - /////////////////////////////////// - // Test LogicalLoraChannelHelper // - /////////////////////////////////// - - // Setup - Ptr channelHelper = CreateObject (); - SubBand subBand1 (869, 869.4, 0.1, 27); - channel1 = CreateObject (868.1); - channel2 = CreateObject (868.3); - channel3 = CreateObject (868.5); - channel4 = CreateObject (869.1); - channel5 = CreateObject (869.3); - - // Channel diagram - // - // Channels 1 2 3 4 5 - // SubBands 868 ----- 0.1% ----- 868.7 869 ----- 1% ----- 869.4 - - // Add SubBands and LogicalLoraChannels to the helper - channelHelper->AddSubBand (&subBand); - channelHelper->AddSubBand (&subBand1); - channelHelper->AddChannel (channel1); - channelHelper->AddChannel (channel2); - channelHelper->AddChannel (channel3); - channelHelper->AddChannel (channel4); - channelHelper->AddChannel (channel5); - - // Duty Cycle tests - // (high level duty cycle behavior) - /////////////////////////////////// - - channelHelper->AddEvent (Seconds (2), channel1); - Time expectedTimeOff = Seconds (2 / 0.01 - 2); - - // Waiting time is computed correctly - NS_TEST_EXPECT_MSG_EQ (channelHelper->GetWaitingTime (channel1), expectedTimeOff, - "Waiting time doesn't behave as expected"); - - // Duty Cycle involves the whole SubBand, not just a channel - NS_TEST_EXPECT_MSG_EQ (channelHelper->GetWaitingTime (channel2), expectedTimeOff, - "Waiting time doesn't behave as expected"); - NS_TEST_EXPECT_MSG_EQ (channelHelper->GetWaitingTime (channel3), expectedTimeOff, - "Waiting time doesn't behave as expected"); - - // Other bands are not affected by this transmission - NS_TEST_EXPECT_MSG_EQ (channelHelper->GetWaitingTime (channel4), Time (0), - "Waiting time affects other subbands"); - NS_TEST_EXPECT_MSG_EQ (channelHelper->GetWaitingTime (channel5), Time (0), - "Waiting time affects other subbands"); + NS_LOG_DEBUG("LogicalLoraChannelTest"); + + ///////////////////////////// + // Test LogicalLoraChannel // + ///////////////////////////// + + // Setup + Ptr channel1 = CreateObject(868); + Ptr channel2 = CreateObject(868); + Ptr channel3 = CreateObject(868.1); + Ptr channel4 = CreateObject(868.001); + + // Equality between channels + // Test the == and != operators + NS_TEST_EXPECT_MSG_EQ(channel1, channel2, "== operator doesn't work as expected"); + NS_TEST_EXPECT_MSG_NE(channel1, channel3, "!= operator doesn't work as expected"); + NS_TEST_EXPECT_MSG_NE(channel1, channel4, "!= operator doesn't work as expected"); + + ////////////////// + // Test SubBand // + ////////////////// + + // Setup + SubBand subBand(868, 868.7, 0.01, 14); + Ptr channel5 = CreateObject(870); + + // Test BelongsToSubBand + NS_TEST_EXPECT_MSG_EQ(subBand.BelongsToSubBand(channel3), + true, + "BelongsToSubBand does not behave as expected"); + NS_TEST_EXPECT_MSG_EQ(subBand.BelongsToSubBand(channel3->GetFrequency()), + true, + "BelongsToSubBand does not behave as expected"); + NS_TEST_EXPECT_MSG_EQ(subBand.BelongsToSubBand(channel5), + false, + "BelongsToSubBand does not behave as expected"); + + /////////////////////////////////// + // Test LogicalLoraChannelHelper // + /////////////////////////////////// + + // Setup + Ptr channelHelper = CreateObject(); + SubBand subBand1(869, 869.4, 0.1, 27); + channel1 = CreateObject(868.1); + channel2 = CreateObject(868.3); + channel3 = CreateObject(868.5); + channel4 = CreateObject(869.1); + channel5 = CreateObject(869.3); + + // Channel diagram + // + // Channels 1 2 3 4 5 + // SubBands 868 ----- 0.1% ----- 868.7 869 ----- 1% ----- 869.4 + + // Add SubBands and LogicalLoraChannels to the helper + channelHelper->AddSubBand(&subBand); + channelHelper->AddSubBand(&subBand1); + channelHelper->AddChannel(channel1); + channelHelper->AddChannel(channel2); + channelHelper->AddChannel(channel3); + channelHelper->AddChannel(channel4); + channelHelper->AddChannel(channel5); + + // Duty Cycle tests + // (high level duty cycle behavior) + /////////////////////////////////// + + channelHelper->AddEvent(Seconds(2), channel1); + Time expectedTimeOff = Seconds(2 / 0.01 - 2); + + // Waiting time is computed correctly + NS_TEST_EXPECT_MSG_EQ(channelHelper->GetWaitingTime(channel1), + expectedTimeOff, + "Waiting time doesn't behave as expected"); + + // Duty Cycle involves the whole SubBand, not just a channel + NS_TEST_EXPECT_MSG_EQ(channelHelper->GetWaitingTime(channel2), + expectedTimeOff, + "Waiting time doesn't behave as expected"); + NS_TEST_EXPECT_MSG_EQ(channelHelper->GetWaitingTime(channel3), + expectedTimeOff, + "Waiting time doesn't behave as expected"); + + // Other bands are not affected by this transmission + NS_TEST_EXPECT_MSG_EQ(channelHelper->GetWaitingTime(channel4), + Time(0), + "Waiting time affects other subbands"); + NS_TEST_EXPECT_MSG_EQ(channelHelper->GetWaitingTime(channel5), + Time(0), + "Waiting time affects other subbands"); } /***************** @@ -855,108 +944,109 @@ LogicalLoraChannelTest::DoRun (void) class TimeOnAirTest : public TestCase { -public: - TimeOnAirTest (); - virtual ~TimeOnAirTest (); + public: + TimeOnAirTest(); + virtual ~TimeOnAirTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -TimeOnAirTest::TimeOnAirTest () - : TestCase ( +TimeOnAirTest::TimeOnAirTest() + : TestCase( "Verify that LoraPhy's function to compute the time on air of a packet works as expected") { } // Reminder that the test case should clean up after itself -TimeOnAirTest::~TimeOnAirTest () +TimeOnAirTest::~TimeOnAirTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -TimeOnAirTest::DoRun (void) +TimeOnAirTest::DoRun(void) { - NS_LOG_DEBUG ("TimeOnAirTest"); - - Ptr packet; - Time duration; - - // Available parameters: - // PayloadSize, SF, HeaderDisabled, CodingRate, Bandwidth, nPreambleSyms, crcEnabled, lowDROptimization - - // Starting parameters - packet = Create (10); - LoraTxParameters txParams; - txParams.sf = 7; - txParams.headerDisabled = false; - txParams.codingRate = 1; - txParams.bandwidthHz = 125000; - txParams.nPreamble = 8; - txParams.crcEnabled = 1; - txParams.lowDataRateOptimizationEnabled = false; - - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.041216, 0.0001, "Unexpected duration"); - - txParams.sf = 8; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.072192, 0.0001, "Unexpected duration"); - - txParams.headerDisabled = true; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.072192, 0.0001, "Unexpected duration"); - - txParams.codingRate = 2; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.078336, 0.0001, "Unexpected duration"); - - txParams.nPreamble = 10; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.082432, 0.0001, "Unexpected duration"); - - txParams.lowDataRateOptimizationEnabled = true; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.082432, 0.0001, "Unexpected duration"); - - txParams.sf = 10; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.280576, 0.0001, "Unexpected duration"); - - txParams.bandwidthHz = 250000; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.14028, 0.0001, "Unexpected duration"); - - txParams.bandwidthHz = 500000; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.070144, 0.0001, "Unexpected duration"); - - txParams.headerDisabled = false; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.082432, 0.0001, "Unexpected duration"); - - txParams.nPreamble = 8; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.078336, 0.0001, "Unexpected duration"); - - txParams.sf = 12; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.264192, 0.0001, "Unexpected duration"); - - packet = Create (50); - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 0.657408, 0.0001, "Unexpected duration"); - - txParams.bandwidthHz = 125000; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 2.629632, 0.0001, "Unexpected duration"); - - txParams.codingRate = 1; - duration = LoraPhy::GetOnAirTime (packet, txParams); - NS_TEST_EXPECT_MSG_EQ_TOL (duration.GetSeconds (), 2.301952, 0.0001, "Unexpected duration"); + NS_LOG_DEBUG("TimeOnAirTest"); + + Ptr packet; + Time duration; + + // Available parameters: + // PayloadSize, SF, HeaderDisabled, CodingRate, Bandwidth, nPreambleSyms, crcEnabled, + // lowDROptimization + + // Starting parameters + packet = Create(10); + LoraTxParameters txParams; + txParams.sf = 7; + txParams.headerDisabled = false; + txParams.codingRate = 1; + txParams.bandwidthHz = 125000; + txParams.nPreamble = 8; + txParams.crcEnabled = 1; + txParams.lowDataRateOptimizationEnabled = false; + + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.041216, 0.0001, "Unexpected duration"); + + txParams.sf = 8; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.072192, 0.0001, "Unexpected duration"); + + txParams.headerDisabled = true; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.072192, 0.0001, "Unexpected duration"); + + txParams.codingRate = 2; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.078336, 0.0001, "Unexpected duration"); + + txParams.nPreamble = 10; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.082432, 0.0001, "Unexpected duration"); + + txParams.lowDataRateOptimizationEnabled = true; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.082432, 0.0001, "Unexpected duration"); + + txParams.sf = 10; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.280576, 0.0001, "Unexpected duration"); + + txParams.bandwidthHz = 250000; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.14028, 0.0001, "Unexpected duration"); + + txParams.bandwidthHz = 500000; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.070144, 0.0001, "Unexpected duration"); + + txParams.headerDisabled = false; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.082432, 0.0001, "Unexpected duration"); + + txParams.nPreamble = 8; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.078336, 0.0001, "Unexpected duration"); + + txParams.sf = 12; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.264192, 0.0001, "Unexpected duration"); + + packet = Create(50); + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 0.657408, 0.0001, "Unexpected duration"); + + txParams.bandwidthHz = 125000; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 2.629632, 0.0001, "Unexpected duration"); + + txParams.codingRate = 1; + duration = LoraPhy::GetOnAirTime(packet, txParams); + NS_TEST_EXPECT_MSG_EQ_TOL(duration.GetSeconds(), 2.301952, 0.0001, "Unexpected duration"); } /************************** @@ -965,399 +1055,459 @@ TimeOnAirTest::DoRun (void) class PhyConnectivityTest : public TestCase { -public: - PhyConnectivityTest (); - virtual ~PhyConnectivityTest (); - void Reset (); - void ReceivedPacket (Ptr packet, uint32_t node); - void UnderSensitivity (Ptr packet, uint32_t node); - void Interference (Ptr packet, uint32_t node); - void NoMoreDemodulators (Ptr packet, uint32_t node); - void WrongFrequency (Ptr packet, uint32_t node); - void WrongSf (Ptr packet, uint32_t node); - bool HaveSamePacketContents (Ptr packet1, Ptr packet2); - -private: - virtual void DoRun (void); - Ptr channel; - Ptr edPhy1; - Ptr edPhy2; - Ptr edPhy3; - - Ptr m_latestReceivedPacket; - int m_receivedPacketCalls = 0; - int m_underSensitivityCalls = 0; - int m_interferenceCalls = 0; - int m_noMoreDemodulatorsCalls = 0; - int m_wrongSfCalls = 0; - int m_wrongFrequencyCalls = 0; + public: + PhyConnectivityTest(); + virtual ~PhyConnectivityTest(); + void Reset(); + void ReceivedPacket(Ptr packet, uint32_t node); + void UnderSensitivity(Ptr packet, uint32_t node); + void Interference(Ptr packet, uint32_t node); + void NoMoreDemodulators(Ptr packet, uint32_t node); + void WrongFrequency(Ptr packet, uint32_t node); + void WrongSf(Ptr packet, uint32_t node); + bool HaveSamePacketContents(Ptr packet1, Ptr packet2); + + private: + virtual void DoRun(void); + Ptr channel; + Ptr edPhy1; + Ptr edPhy2; + Ptr edPhy3; + + Ptr m_latestReceivedPacket; + int m_receivedPacketCalls = 0; + int m_underSensitivityCalls = 0; + int m_interferenceCalls = 0; + int m_noMoreDemodulatorsCalls = 0; + int m_wrongSfCalls = 0; + int m_wrongFrequencyCalls = 0; }; // Add some help text to this case to describe what it is intended to test -PhyConnectivityTest::PhyConnectivityTest () - : TestCase ("Verify that PhyConnectivity works as expected") +PhyConnectivityTest::PhyConnectivityTest() + : TestCase("Verify that PhyConnectivity works as expected") { } // Reminder that the test case should clean up after itself -PhyConnectivityTest::~PhyConnectivityTest () +PhyConnectivityTest::~PhyConnectivityTest() { } void -PhyConnectivityTest::ReceivedPacket (Ptr packet, uint32_t node) +PhyConnectivityTest::ReceivedPacket(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_receivedPacketCalls++; + m_receivedPacketCalls++; - m_latestReceivedPacket = packet->Copy (); + m_latestReceivedPacket = packet->Copy(); } void -PhyConnectivityTest::UnderSensitivity (Ptr packet, uint32_t node) +PhyConnectivityTest::UnderSensitivity(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_underSensitivityCalls++; + m_underSensitivityCalls++; } void -PhyConnectivityTest::Interference (Ptr packet, uint32_t node) +PhyConnectivityTest::Interference(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_interferenceCalls++; + m_interferenceCalls++; } void -PhyConnectivityTest::NoMoreDemodulators (Ptr packet, uint32_t node) +PhyConnectivityTest::NoMoreDemodulators(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_noMoreDemodulatorsCalls++; + m_noMoreDemodulatorsCalls++; } void -PhyConnectivityTest::WrongSf (Ptr packet, uint32_t node) +PhyConnectivityTest::WrongSf(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_wrongSfCalls++; + m_wrongSfCalls++; } void -PhyConnectivityTest::WrongFrequency (Ptr packet, uint32_t node) +PhyConnectivityTest::WrongFrequency(Ptr packet, uint32_t node) { - NS_LOG_FUNCTION (packet << node); + NS_LOG_FUNCTION(packet << node); - m_wrongFrequencyCalls++; + m_wrongFrequencyCalls++; } bool -PhyConnectivityTest::HaveSamePacketContents (Ptr packet1, Ptr packet2) +PhyConnectivityTest::HaveSamePacketContents(Ptr packet1, Ptr packet2) { - uint32_t size1 = packet1->GetSerializedSize (); - uint8_t buffer1[size1]; - packet1->Serialize (buffer1, size1); + uint32_t size1 = packet1->GetSerializedSize(); + uint8_t buffer1[size1]; + packet1->Serialize(buffer1, size1); - uint32_t size2 = packet2->GetSerializedSize (); - uint8_t buffer2[size2]; - packet2->Serialize (buffer2, size2); + uint32_t size2 = packet2->GetSerializedSize(); + uint8_t buffer2[size2]; + packet2->Serialize(buffer2, size2); - NS_ASSERT (size1 == size2); + NS_ASSERT(size1 == size2); - bool foundADifference = false; - for (uint32_t i = 0; i < size1; i++) + bool foundADifference = false; + for (uint32_t i = 0; i < size1; i++) { - NS_LOG_DEBUG (unsigned (buffer1[i]) << " " << unsigned (buffer2[i])); - if (buffer1[i] != buffer2[i]) + NS_LOG_DEBUG(unsigned(buffer1[i]) << " " << unsigned(buffer2[i])); + if (buffer1[i] != buffer2[i]) { - foundADifference = true; - break; + foundADifference = true; + break; } } - return !foundADifference; + return !foundADifference; } void -PhyConnectivityTest::Reset (void) +PhyConnectivityTest::Reset(void) { - m_receivedPacketCalls = 0; - m_underSensitivityCalls = 0; - m_interferenceCalls = 0; - m_wrongSfCalls = 0; - m_wrongFrequencyCalls = 0; - - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); - - Ptr delay = CreateObject (); - - // Create the channel - channel = CreateObject (loss, delay); - - // Connect PHYs - edPhy1 = CreateObject (); - edPhy2 = CreateObject (); - edPhy3 = CreateObject (); - - edPhy1->SetFrequency (868.1); - edPhy2->SetFrequency (868.1); - edPhy3->SetFrequency (868.1); - - Ptr mob1 = CreateObject (); - Ptr mob2 = CreateObject (); - Ptr mob3 = CreateObject (); - - mob1->SetPosition (Vector (0.0, 0.0, 0.0)); - mob2->SetPosition (Vector (10.0, 0.0, 0.0)); - mob3->SetPosition (Vector (20.0, 0.0, 0.0)); - - edPhy1->SetMobility (mob1); - edPhy2->SetMobility (mob2); - edPhy3->SetMobility (mob3); - - edPhy1->SwitchToStandby (); - edPhy2->SwitchToStandby (); - edPhy3->SwitchToStandby (); - - channel->Add (edPhy1); - channel->Add (edPhy2); - channel->Add (edPhy3); - - edPhy1->SetChannel (channel); - edPhy2->SetChannel (channel); - edPhy3->SetChannel (channel); - - // Listen for a specific SpreadingFactor - edPhy1->SetSpreadingFactor (12); - edPhy2->SetSpreadingFactor (12); - edPhy3->SetSpreadingFactor (12); - - // Listen on a specific frequency - edPhy1->SetFrequency (868.1); - edPhy2->SetFrequency (868.1); - edPhy3->SetFrequency (868.1); - - edPhy1->TraceConnectWithoutContext ("ReceivedPacket", - MakeCallback (&PhyConnectivityTest::ReceivedPacket, this)); - edPhy2->TraceConnectWithoutContext ("ReceivedPacket", - MakeCallback (&PhyConnectivityTest::ReceivedPacket, this)); - edPhy3->TraceConnectWithoutContext ("ReceivedPacket", - MakeCallback (&PhyConnectivityTest::ReceivedPacket, this)); - - edPhy1->TraceConnectWithoutContext ("LostPacketBecauseUnderSensitivity", - MakeCallback (&PhyConnectivityTest::UnderSensitivity, this)); - edPhy2->TraceConnectWithoutContext ("LostPacketBecauseUnderSensitivity", - MakeCallback (&PhyConnectivityTest::UnderSensitivity, this)); - edPhy3->TraceConnectWithoutContext ("LostPacketBecauseUnderSensitivity", - MakeCallback (&PhyConnectivityTest::UnderSensitivity, this)); - - edPhy1->TraceConnectWithoutContext ("LostPacketBecauseInterference", - MakeCallback (&PhyConnectivityTest::Interference, this)); - edPhy2->TraceConnectWithoutContext ("LostPacketBecauseInterference", - MakeCallback (&PhyConnectivityTest::Interference, this)); - edPhy3->TraceConnectWithoutContext ("LostPacketBecauseInterference", - MakeCallback (&PhyConnectivityTest::Interference, this)); - - edPhy1->TraceConnectWithoutContext ( - "LostPacketBecauseNoMoreReceivers", - MakeCallback (&PhyConnectivityTest::NoMoreDemodulators, this)); - edPhy2->TraceConnectWithoutContext ( - "LostPacketBecauseNoMoreReceivers", - MakeCallback (&PhyConnectivityTest::NoMoreDemodulators, this)); - edPhy3->TraceConnectWithoutContext ( - "LostPacketBecauseNoMoreReceivers", - MakeCallback (&PhyConnectivityTest::NoMoreDemodulators, this)); - - edPhy1->TraceConnectWithoutContext ("LostPacketBecauseWrongFrequency", - MakeCallback (&PhyConnectivityTest::WrongFrequency, this)); - edPhy2->TraceConnectWithoutContext ("LostPacketBecauseWrongFrequency", - MakeCallback (&PhyConnectivityTest::WrongFrequency, this)); - edPhy3->TraceConnectWithoutContext ("LostPacketBecauseWrongFrequency", - MakeCallback (&PhyConnectivityTest::WrongFrequency, this)); - - edPhy1->TraceConnectWithoutContext ("LostPacketBecauseWrongSpreadingFactor", - MakeCallback (&PhyConnectivityTest::WrongSf, this)); - edPhy2->TraceConnectWithoutContext ("LostPacketBecauseWrongSpreadingFactor", - MakeCallback (&PhyConnectivityTest::WrongSf, this)); - edPhy3->TraceConnectWithoutContext ("LostPacketBecauseWrongSpreadingFactor", - MakeCallback (&PhyConnectivityTest::WrongSf, this)); + m_receivedPacketCalls = 0; + m_underSensitivityCalls = 0; + m_interferenceCalls = 0; + m_wrongSfCalls = 0; + m_wrongFrequencyCalls = 0; + + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); + + Ptr delay = CreateObject(); + + // Create the channel + channel = CreateObject(loss, delay); + + // Connect PHYs + edPhy1 = CreateObject(); + edPhy2 = CreateObject(); + edPhy3 = CreateObject(); + + edPhy1->SetFrequency(868.1); + edPhy2->SetFrequency(868.1); + edPhy3->SetFrequency(868.1); + + Ptr mob1 = CreateObject(); + Ptr mob2 = CreateObject(); + Ptr mob3 = CreateObject(); + + mob1->SetPosition(Vector(0.0, 0.0, 0.0)); + mob2->SetPosition(Vector(10.0, 0.0, 0.0)); + mob3->SetPosition(Vector(20.0, 0.0, 0.0)); + + edPhy1->SetMobility(mob1); + edPhy2->SetMobility(mob2); + edPhy3->SetMobility(mob3); + + edPhy1->SwitchToStandby(); + edPhy2->SwitchToStandby(); + edPhy3->SwitchToStandby(); + + channel->Add(edPhy1); + channel->Add(edPhy2); + channel->Add(edPhy3); + + edPhy1->SetChannel(channel); + edPhy2->SetChannel(channel); + edPhy3->SetChannel(channel); + + // Listen for a specific SpreadingFactor + edPhy1->SetSpreadingFactor(12); + edPhy2->SetSpreadingFactor(12); + edPhy3->SetSpreadingFactor(12); + + // Listen on a specific frequency + edPhy1->SetFrequency(868.1); + edPhy2->SetFrequency(868.1); + edPhy3->SetFrequency(868.1); + + edPhy1->TraceConnectWithoutContext("ReceivedPacket", + MakeCallback(&PhyConnectivityTest::ReceivedPacket, this)); + edPhy2->TraceConnectWithoutContext("ReceivedPacket", + MakeCallback(&PhyConnectivityTest::ReceivedPacket, this)); + edPhy3->TraceConnectWithoutContext("ReceivedPacket", + MakeCallback(&PhyConnectivityTest::ReceivedPacket, this)); + + edPhy1->TraceConnectWithoutContext("LostPacketBecauseUnderSensitivity", + MakeCallback(&PhyConnectivityTest::UnderSensitivity, this)); + edPhy2->TraceConnectWithoutContext("LostPacketBecauseUnderSensitivity", + MakeCallback(&PhyConnectivityTest::UnderSensitivity, this)); + edPhy3->TraceConnectWithoutContext("LostPacketBecauseUnderSensitivity", + MakeCallback(&PhyConnectivityTest::UnderSensitivity, this)); + + edPhy1->TraceConnectWithoutContext("LostPacketBecauseInterference", + MakeCallback(&PhyConnectivityTest::Interference, this)); + edPhy2->TraceConnectWithoutContext("LostPacketBecauseInterference", + MakeCallback(&PhyConnectivityTest::Interference, this)); + edPhy3->TraceConnectWithoutContext("LostPacketBecauseInterference", + MakeCallback(&PhyConnectivityTest::Interference, this)); + + edPhy1->TraceConnectWithoutContext( + "LostPacketBecauseNoMoreReceivers", + MakeCallback(&PhyConnectivityTest::NoMoreDemodulators, this)); + edPhy2->TraceConnectWithoutContext( + "LostPacketBecauseNoMoreReceivers", + MakeCallback(&PhyConnectivityTest::NoMoreDemodulators, this)); + edPhy3->TraceConnectWithoutContext( + "LostPacketBecauseNoMoreReceivers", + MakeCallback(&PhyConnectivityTest::NoMoreDemodulators, this)); + + edPhy1->TraceConnectWithoutContext("LostPacketBecauseWrongFrequency", + MakeCallback(&PhyConnectivityTest::WrongFrequency, this)); + edPhy2->TraceConnectWithoutContext("LostPacketBecauseWrongFrequency", + MakeCallback(&PhyConnectivityTest::WrongFrequency, this)); + edPhy3->TraceConnectWithoutContext("LostPacketBecauseWrongFrequency", + MakeCallback(&PhyConnectivityTest::WrongFrequency, this)); + + edPhy1->TraceConnectWithoutContext("LostPacketBecauseWrongSpreadingFactor", + MakeCallback(&PhyConnectivityTest::WrongSf, this)); + edPhy2->TraceConnectWithoutContext("LostPacketBecauseWrongSpreadingFactor", + MakeCallback(&PhyConnectivityTest::WrongSf, this)); + edPhy3->TraceConnectWithoutContext("LostPacketBecauseWrongSpreadingFactor", + MakeCallback(&PhyConnectivityTest::WrongSf, this)); } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -PhyConnectivityTest::DoRun (void) +PhyConnectivityTest::DoRun(void) { - NS_LOG_DEBUG ("PhyConnectivityTest"); - - // Setup - //////// - - Reset (); - - LoraTxParameters txParams; - txParams.sf = 12; - - uint8_t buffer[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - Ptr packet = Create (buffer, 10); - - // Testing - ////////// - - // Basic packet delivery test - ///////////////////////////// - - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ ( - m_receivedPacketCalls, 2, - "Channel skipped some PHYs when delivering a packet"); // All PHYs except the sender - - Reset (); - - // Sleeping PHYs do not receive the packet - - edPhy2->SwitchToSleep (); - - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ ( - m_receivedPacketCalls, 1, - "Packet was received by a PHY in SLEEP mode"); // All PHYs in Standby except the sender - - Reset (); - - // Packet that arrives under sensitivity is received correctly if SF increases - - txParams.sf = 7; - edPhy2->SetSpreadingFactor (7); - edPhy2->GetMobility ()->GetObject ()->SetPosition ( - Vector (2990, 0, 0)); - - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ ( - m_underSensitivityCalls, 1, - "Packet that should have been lost because of low receive power was recevied"); - - Reset (); - - // Try again using a packet with higher SF - txParams.sf = 8; - edPhy2->SetSpreadingFactor (8); - edPhy2->GetMobility ()->GetObject ()->SetPosition ( - Vector (2990, 0, 0)); - - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ (m_underSensitivityCalls, 0, - "Packets that should have arrived above sensitivity were under it"); - - Reset (); - - // Packets can be destroyed by interference - - txParams.sf = 12; - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy3, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ (m_interferenceCalls, 1, - "Packets that should be destroyed by interference weren't"); - - Reset (); - - // Packets can be lost because the PHY is not listening on the right frequency - - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.3, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ (m_wrongFrequencyCalls, 2, - "Packets were received even though PHY was on a different frequency"); - - Reset (); - - // Packets can be lost because the PHY is not listening for the right SF - - txParams.sf = 8; // Send with 8, listening for 12 - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); - - NS_TEST_EXPECT_MSG_EQ (m_wrongSfCalls, 2, - "Packets were received even though PHY was listening for a different SF"); - - Reset (); - - // Sending of packets - ///////////////////// - - // The very same packet arrives at the other PHY - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); - - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); + NS_LOG_DEBUG("PhyConnectivityTest"); - NS_TEST_EXPECT_MSG_EQ (HaveSamePacketContents (packet, m_latestReceivedPacket), true, - "Packet changed contents when going through the channel"); + // Setup + //////// - Reset (); + Reset(); - // Correct state transitions - //////////////////////////// + LoraTxParameters txParams; + txParams.sf = 12; - // PHY switches to STANDBY after TX and RX + uint8_t buffer[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + Ptr packet = Create(buffer, 10); - Simulator::Schedule (Seconds (2), &SimpleEndDeviceLoraPhy::Send, edPhy1, packet, txParams, 868.1, - 14); + // Testing + ////////// - Simulator::Stop (Hours (2)); - Simulator::Run (); - Simulator::Destroy (); + // Basic packet delivery test + ///////////////////////////// - NS_TEST_EXPECT_MSG_EQ (edPhy1->GetState (), SimpleEndDeviceLoraPhy::STANDBY, - "State didn't switch to STANDBY as expected"); - NS_TEST_EXPECT_MSG_EQ (edPhy2->GetState (), SimpleEndDeviceLoraPhy::STANDBY, - "State didn't switch to STANDBY as expected"); + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ( + m_receivedPacketCalls, + 2, + "Channel skipped some PHYs when delivering a packet"); // All PHYs except the sender + + Reset(); + + // Sleeping PHYs do not receive the packet + + edPhy2->SwitchToSleep(); + + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ( + m_receivedPacketCalls, + 1, + "Packet was received by a PHY in SLEEP mode"); // All PHYs in Standby except the sender + + Reset(); + + // Packet that arrives under sensitivity is received correctly if SF increases + + txParams.sf = 7; + edPhy2->SetSpreadingFactor(7); + edPhy2->GetMobility()->GetObject()->SetPosition( + Vector(2990, 0, 0)); + + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ( + m_underSensitivityCalls, + 1, + "Packet that should have been lost because of low receive power was recevied"); + + Reset(); + + // Try again using a packet with higher SF + txParams.sf = 8; + edPhy2->SetSpreadingFactor(8); + edPhy2->GetMobility()->GetObject()->SetPosition( + Vector(2990, 0, 0)); + + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(m_underSensitivityCalls, + 0, + "Packets that should have arrived above sensitivity were under it"); + + Reset(); + + // Packets can be destroyed by interference + + txParams.sf = 12; + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy3, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(m_interferenceCalls, + 1, + "Packets that should be destroyed by interference weren't"); + + Reset(); + + // Packets can be lost because the PHY is not listening on the right frequency + + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.3, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(m_wrongFrequencyCalls, + 2, + "Packets were received even though PHY was on a different frequency"); + + Reset(); + + // Packets can be lost because the PHY is not listening for the right SF + + txParams.sf = 8; // Send with 8, listening for 12 + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(m_wrongSfCalls, + 2, + "Packets were received even though PHY was listening for a different SF"); + + Reset(); + + // Sending of packets + ///////////////////// + + // The very same packet arrives at the other PHY + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(HaveSamePacketContents(packet, m_latestReceivedPacket), + true, + "Packet changed contents when going through the channel"); + + Reset(); + + // Correct state transitions + //////////////////////////// + + // PHY switches to STANDBY after TX and RX + + Simulator::Schedule(Seconds(2), + &SimpleEndDeviceLoraPhy::Send, + edPhy1, + packet, + txParams, + 868.1, + 14); + + Simulator::Stop(Hours(2)); + Simulator::Run(); + Simulator::Destroy(); + + NS_TEST_EXPECT_MSG_EQ(edPhy1->GetState(), + SimpleEndDeviceLoraPhy::STANDBY, + "State didn't switch to STANDBY as expected"); + NS_TEST_EXPECT_MSG_EQ(edPhy2->GetState(), + SimpleEndDeviceLoraPhy::STANDBY, + "State didn't switch to STANDBY as expected"); } /***************** @@ -1366,31 +1516,31 @@ PhyConnectivityTest::DoRun (void) class LorawanMacTest : public TestCase { -public: - LorawanMacTest (); - virtual ~LorawanMacTest (); + public: + LorawanMacTest(); + virtual ~LorawanMacTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -LorawanMacTest::LorawanMacTest () - : TestCase ("Verify that the MAC layer of EDs behaves as expected") +LorawanMacTest::LorawanMacTest() + : TestCase("Verify that the MAC layer of EDs behaves as expected") { } // Reminder that the test case should clean up after itself -LorawanMacTest::~LorawanMacTest () +LorawanMacTest::~LorawanMacTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -LorawanMacTest::DoRun (void) +LorawanMacTest::DoRun(void) { - NS_LOG_DEBUG ("LorawanMacTest"); + NS_LOG_DEBUG("LorawanMacTest"); } /************** @@ -1403,21 +1553,22 @@ LorawanMacTest::DoRun (void) class LorawanTestSuite : public TestSuite { -public: - LorawanTestSuite (); + public: + LorawanTestSuite(); }; -LorawanTestSuite::LorawanTestSuite () : TestSuite ("lorawan", UNIT) +LorawanTestSuite::LorawanTestSuite() + : TestSuite("lorawan", UNIT) { - LogComponentEnable ("LorawanTestSuite", LOG_LEVEL_DEBUG); - // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER - AddTestCase (new InterferenceTest, TestCase::QUICK); - AddTestCase (new AddressTest, TestCase::QUICK); - AddTestCase (new HeaderTest, TestCase::QUICK); - AddTestCase (new ReceivePathTest, TestCase::QUICK); - AddTestCase (new LogicalLoraChannelTest, TestCase::QUICK); - AddTestCase (new TimeOnAirTest, TestCase::QUICK); - AddTestCase (new PhyConnectivityTest, TestCase::QUICK); + LogComponentEnable("LorawanTestSuite", LOG_LEVEL_DEBUG); + // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER + AddTestCase(new InterferenceTest, TestCase::QUICK); + AddTestCase(new AddressTest, TestCase::QUICK); + AddTestCase(new HeaderTest, TestCase::QUICK); + AddTestCase(new ReceivePathTest, TestCase::QUICK); + AddTestCase(new LogicalLoraChannelTest, TestCase::QUICK); + AddTestCase(new TimeOnAirTest, TestCase::QUICK); + AddTestCase(new PhyConnectivityTest, TestCase::QUICK); } // Do not forget to allocate an instance of this TestSuite diff --git a/test/network-scheduler-test-suite.cc b/test/network-scheduler-test-suite.cc index 52ad61b9b9..025259db0b 100644 --- a/test/network-scheduler-test-suite.cc +++ b/test/network-scheduler-test-suite.cc @@ -13,7 +13,7 @@ using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("NetworkSchedulerTestSuite"); +NS_LOG_COMPONENT_DEFINE("NetworkSchedulerTestSuite"); ///////////////////////////// // NetworkStatus testing // @@ -21,35 +21,34 @@ NS_LOG_COMPONENT_DEFINE ("NetworkSchedulerTestSuite"); class NetworkSchedulerTest : public TestCase { -public: - NetworkSchedulerTest (); - virtual ~NetworkSchedulerTest (); + public: + NetworkSchedulerTest(); + virtual ~NetworkSchedulerTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -NetworkSchedulerTest::NetworkSchedulerTest () - : TestCase ("Verify correct behavior of the NetworkScheduler object") +NetworkSchedulerTest::NetworkSchedulerTest() + : TestCase("Verify correct behavior of the NetworkScheduler object") { } // Reminder that the test case should clean up after itself -NetworkSchedulerTest::~NetworkSchedulerTest () +NetworkSchedulerTest::~NetworkSchedulerTest() { } - // This method is the pure virtual method from class TestCase that every // TestCase must implement void -NetworkSchedulerTest::DoRun (void) +NetworkSchedulerTest::DoRun(void) { - NS_LOG_DEBUG ("NetworkSchedulerTest"); + NS_LOG_DEBUG("NetworkSchedulerTest"); - // If a packet is received at the network server, a reply event should be - // scheduled to happen 1 second after the reception. + // If a packet is received at the network server, a reply event should be + // scheduled to happen 1 second after the reception. } /************** @@ -62,16 +61,16 @@ NetworkSchedulerTest::DoRun (void) class NetworkSchedulerTestSuite : public TestSuite { -public: - NetworkSchedulerTestSuite (); + public: + NetworkSchedulerTestSuite(); }; -NetworkSchedulerTestSuite::NetworkSchedulerTestSuite () - : TestSuite ("network-scheduler", UNIT) +NetworkSchedulerTestSuite::NetworkSchedulerTestSuite() + : TestSuite("network-scheduler", UNIT) { - LogComponentEnable ("NetworkSchedulerTestSuite", LOG_LEVEL_DEBUG); - // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER - AddTestCase (new NetworkSchedulerTest, TestCase::QUICK); + LogComponentEnable("NetworkSchedulerTestSuite", LOG_LEVEL_DEBUG); + // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER + AddTestCase(new NetworkSchedulerTest, TestCase::QUICK); } // Do not forget to allocate an instance of this TestSuite diff --git a/test/network-server-test-suite.cc b/test/network-server-test-suite.cc index 3134edcefd..834c9bdea1 100644 --- a/test/network-server-test-suite.cc +++ b/test/network-server-test-suite.cc @@ -9,12 +9,13 @@ */ // Include headers of classes to test -#include "ns3/log.h" #include "utilities.h" -#include "ns3/core-module.h" + #include "ns3/callback.h" -#include "ns3/network-server.h" +#include "ns3/core-module.h" +#include "ns3/log.h" #include "ns3/network-server-helper.h" +#include "ns3/network-server.h" // An essential include is test.h #include "ns3/test.h" @@ -22,7 +23,7 @@ using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("NetworkServerTestSuite"); +NS_LOG_COMPONENT_DEFINE("NetworkServerTestSuite"); /////////////////////////// // NetworkServer testing // @@ -30,75 +31,72 @@ NS_LOG_COMPONENT_DEFINE ("NetworkServerTestSuite"); class UplinkPacketTest : public TestCase { -public: - UplinkPacketTest (); - virtual ~UplinkPacketTest (); + public: + UplinkPacketTest(); + virtual ~UplinkPacketTest(); - void ReceivedPacket (Ptr packet); - void SendPacket (Ptr endDevice); + void ReceivedPacket(Ptr packet); + void SendPacket(Ptr endDevice); -private: - virtual void DoRun (void); - bool m_receivedPacket = false; + private: + virtual void DoRun(void); + bool m_receivedPacket = false; }; // Add some help text to this case to describe what it is intended to test -UplinkPacketTest::UplinkPacketTest () - : TestCase ("Verify that the NetworkServer can receive" - " packets sent in the uplink by devices") +UplinkPacketTest::UplinkPacketTest() + : TestCase("Verify that the NetworkServer can receive" + " packets sent in the uplink by devices") { } // Reminder that the test case should clean up after itself -UplinkPacketTest::~UplinkPacketTest () +UplinkPacketTest::~UplinkPacketTest() { } void -UplinkPacketTest::ReceivedPacket (Ptr packet) +UplinkPacketTest::ReceivedPacket(Ptr packet) { - NS_LOG_DEBUG ("Received a packet at the NS"); - m_receivedPacket = true; + NS_LOG_DEBUG("Received a packet at the NS"); + m_receivedPacket = true; } void -UplinkPacketTest::SendPacket (Ptr endDevice) +UplinkPacketTest::SendPacket(Ptr endDevice) { - endDevice->GetDevice (0)->Send (Create (20), Address (), 0); + endDevice->GetDevice(0)->Send(Create(20), Address(), 0); } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -UplinkPacketTest::DoRun (void) +UplinkPacketTest::DoRun(void) { - NS_LOG_DEBUG ("UplinkPacketTest"); + NS_LOG_DEBUG("UplinkPacketTest"); - // Create a bunch of actual devices - NetworkComponents components = InitializeNetwork (1, 1); + // Create a bunch of actual devices + NetworkComponents components = InitializeNetwork(1, 1); - Ptr channel = components.channel; - NodeContainer endDevices = components.endDevices; - NodeContainer gateways = components.gateways; - Ptr nsNode = components.nsNode; + Ptr channel = components.channel; + NodeContainer endDevices = components.endDevices; + NodeContainer gateways = components.gateways; + Ptr nsNode = components.nsNode; - // Connect the trace source for received packets - nsNode->GetApplication (0)->TraceConnectWithoutContext - ("ReceivedPacket", - MakeCallback - (&UplinkPacketTest::ReceivedPacket, - this)); + // Connect the trace source for received packets + nsNode->GetApplication(0)->TraceConnectWithoutContext( + "ReceivedPacket", + MakeCallback(&UplinkPacketTest::ReceivedPacket, this)); - // Send a packet - Simulator::Schedule (Seconds (1), &UplinkPacketTest::SendPacket, this, - endDevices.Get (0)); + // Send a packet + Simulator::Schedule(Seconds(1), &UplinkPacketTest::SendPacket, this, endDevices.Get(0)); - Simulator::Stop (Seconds (5)); - Simulator::Run (); - Simulator::Destroy (); + Simulator::Stop(Seconds(5)); + Simulator::Run(); + Simulator::Destroy(); - // Check that we received the packet - NS_ASSERT (m_receivedPacket == true); + // Check that we received the packet + NS_ASSERT(m_receivedPacket == true); } //////////////////////// @@ -107,77 +105,90 @@ UplinkPacketTest::DoRun (void) class DownlinkPacketTest : public TestCase { -public: - DownlinkPacketTest (); - virtual ~DownlinkPacketTest (); - - void ReceivedPacketAtEndDevice (uint8_t requiredTransmissions, bool success, - Time time, Ptr packet); - void SendPacket (Ptr endDevice, bool requestAck); - -private: - virtual void DoRun (void); - bool m_receivedPacketAtEd = false; + public: + DownlinkPacketTest(); + virtual ~DownlinkPacketTest(); + + void ReceivedPacketAtEndDevice(uint8_t requiredTransmissions, + bool success, + Time time, + Ptr packet); + void SendPacket(Ptr endDevice, bool requestAck); + + private: + virtual void DoRun(void); + bool m_receivedPacketAtEd = false; }; // Add some help text to this case to describe what it is intended to test -DownlinkPacketTest::DownlinkPacketTest () - : TestCase ("Verify that devices requesting an acknowledgment receive" - " a reply from the Network Server.") +DownlinkPacketTest::DownlinkPacketTest() + : TestCase("Verify that devices requesting an acknowledgment receive" + " a reply from the Network Server.") { } // Reminder that the test case should clean up after itself -DownlinkPacketTest::~DownlinkPacketTest () +DownlinkPacketTest::~DownlinkPacketTest() { } void -DownlinkPacketTest::ReceivedPacketAtEndDevice (uint8_t requiredTransmissions, bool success, Time time, Ptr packet) +DownlinkPacketTest::ReceivedPacketAtEndDevice(uint8_t requiredTransmissions, + bool success, + Time time, + Ptr packet) { - NS_LOG_DEBUG ("Received a packet at the ED"); - m_receivedPacketAtEd = success; + NS_LOG_DEBUG("Received a packet at the ED"); + m_receivedPacketAtEd = success; } void -DownlinkPacketTest::SendPacket (Ptr endDevice, bool requestAck) +DownlinkPacketTest::SendPacket(Ptr endDevice, bool requestAck) { - if (requestAck) + if (requestAck) { - endDevice->GetDevice (0)->GetObject ()->GetMac - ()->GetObject ()->SetMType - (LorawanMacHeader::CONFIRMED_DATA_UP); + endDevice->GetDevice(0) + ->GetObject() + ->GetMac() + ->GetObject() + ->SetMType(LorawanMacHeader::CONFIRMED_DATA_UP); } - endDevice->GetDevice (0)->Send (Create (20), Address (), 0); + endDevice->GetDevice(0)->Send(Create(20), Address(), 0); } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -DownlinkPacketTest::DoRun (void) +DownlinkPacketTest::DoRun(void) { - NS_LOG_DEBUG ("DownlinkPacketTest"); - - // Create a bunch of actual devices - NetworkComponents components = InitializeNetwork (1, 1); - - Ptr channel = components.channel; - NodeContainer endDevices = components.endDevices; - NodeContainer gateways = components.gateways; - Ptr nsNode = components.nsNode; - - // Connect the ED's trace source for received packets - endDevices.Get (0)->GetDevice (0)->GetObject()->GetMac ()->GetObject()->TraceConnectWithoutContext ("RequiredTransmissions", MakeCallback (&DownlinkPacketTest::ReceivedPacketAtEndDevice, this)); - - // Send a packet in uplink - Simulator::Schedule (Seconds (1), &DownlinkPacketTest::SendPacket, this, - endDevices.Get (0), true); - - Simulator::Stop (Seconds (10)); // Allow for time to receive a downlink packet - Simulator::Run (); - Simulator::Destroy (); - - NS_ASSERT (m_receivedPacketAtEd); + NS_LOG_DEBUG("DownlinkPacketTest"); + + // Create a bunch of actual devices + NetworkComponents components = InitializeNetwork(1, 1); + + Ptr channel = components.channel; + NodeContainer endDevices = components.endDevices; + NodeContainer gateways = components.gateways; + Ptr nsNode = components.nsNode; + + // Connect the ED's trace source for received packets + endDevices.Get(0) + ->GetDevice(0) + ->GetObject() + ->GetMac() + ->GetObject() + ->TraceConnectWithoutContext( + "RequiredTransmissions", + MakeCallback(&DownlinkPacketTest::ReceivedPacketAtEndDevice, this)); + + // Send a packet in uplink + Simulator::Schedule(Seconds(1), &DownlinkPacketTest::SendPacket, this, endDevices.Get(0), true); + + Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet + Simulator::Run(); + Simulator::Destroy(); + + NS_ASSERT(m_receivedPacketAtEd); } ////////////////////////// @@ -186,85 +197,91 @@ DownlinkPacketTest::DoRun (void) class LinkCheckTest : public TestCase { -public: - LinkCheckTest (); - virtual ~LinkCheckTest (); + public: + LinkCheckTest(); + virtual ~LinkCheckTest(); - void LastKnownGatewayCount (int newValue, int oldValue); + void LastKnownGatewayCount(int newValue, int oldValue); - void SendPacket (Ptr endDevice, bool requestAck); + void SendPacket(Ptr endDevice, bool requestAck); -private: - virtual void DoRun (void); - bool m_receivedPacketAtEd = false; - int m_numberOfGatewaysThatReceivedPacket = 0; + private: + virtual void DoRun(void); + bool m_receivedPacketAtEd = false; + int m_numberOfGatewaysThatReceivedPacket = 0; }; // Add some help text to this case to describe what it is intended to test -LinkCheckTest::LinkCheckTest () - : TestCase ("Verify that the NetworkServer correctly responds to " - "LinkCheck requests") +LinkCheckTest::LinkCheckTest() + : TestCase("Verify that the NetworkServer correctly responds to " + "LinkCheck requests") { } // Reminder that the test case should clean up after itself -LinkCheckTest::~LinkCheckTest () +LinkCheckTest::~LinkCheckTest() { } void -LinkCheckTest::LastKnownGatewayCount (int newValue, - int oldValue) +LinkCheckTest::LastKnownGatewayCount(int newValue, int oldValue) { - NS_LOG_DEBUG ("Updated Gateway Count"); - m_receivedPacketAtEd = true; + NS_LOG_DEBUG("Updated Gateway Count"); + m_receivedPacketAtEd = true; - m_numberOfGatewaysThatReceivedPacket = newValue; + m_numberOfGatewaysThatReceivedPacket = newValue; } void -LinkCheckTest::SendPacket (Ptr endDevice, bool requestAck) +LinkCheckTest::SendPacket(Ptr endDevice, bool requestAck) { - Ptr macLayer = endDevice->GetDevice - (0)->GetObject ()->GetMac ()->GetObject (); + Ptr macLayer = endDevice->GetDevice(0) + ->GetObject() + ->GetMac() + ->GetObject(); - if (requestAck) + if (requestAck) { - macLayer->SetMType (LorawanMacHeader::CONFIRMED_DATA_UP); + macLayer->SetMType(LorawanMacHeader::CONFIRMED_DATA_UP); } - macLayer->AddMacCommand (Create ()); + macLayer->AddMacCommand(Create()); - endDevice->GetDevice (0)->Send (Create (20), Address (), 0); + endDevice->GetDevice(0)->Send(Create(20), Address(), 0); } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -LinkCheckTest::DoRun (void) +LinkCheckTest::DoRun(void) { - NS_LOG_DEBUG ("LinkCheckTest"); + NS_LOG_DEBUG("LinkCheckTest"); - // Create a bunch of actual devices - NetworkComponents components = InitializeNetwork (1, 1); + // Create a bunch of actual devices + NetworkComponents components = InitializeNetwork(1, 1); - Ptr channel = components.channel; - NodeContainer endDevices = components.endDevices; - NodeContainer gateways = components.gateways; - Ptr nsNode = components.nsNode; + Ptr channel = components.channel; + NodeContainer endDevices = components.endDevices; + NodeContainer gateways = components.gateways; + Ptr nsNode = components.nsNode; - // Connect the ED's trace source for Last known Gateway Count - endDevices.Get (0)->GetDevice (0)->GetObject()->GetMac ()->GetObject()->TraceConnectWithoutContext ("LastKnownGatewayCount", MakeCallback (&LinkCheckTest::LastKnownGatewayCount, this)); + // Connect the ED's trace source for Last known Gateway Count + endDevices.Get(0) + ->GetDevice(0) + ->GetObject() + ->GetMac() + ->GetObject() + ->TraceConnectWithoutContext("LastKnownGatewayCount", + MakeCallback(&LinkCheckTest::LastKnownGatewayCount, this)); - // Send a packet in uplink - Simulator::Schedule (Seconds (1), &LinkCheckTest::SendPacket, this, - endDevices.Get (0), true); + // Send a packet in uplink + Simulator::Schedule(Seconds(1), &LinkCheckTest::SendPacket, this, endDevices.Get(0), true); - Simulator::Stop (Seconds (10)); // Allow for time to receive a downlink packet - Simulator::Run (); - Simulator::Destroy (); + Simulator::Stop(Seconds(10)); // Allow for time to receive a downlink packet + Simulator::Run(); + Simulator::Destroy(); - NS_ASSERT (m_receivedPacketAtEd); + NS_ASSERT(m_receivedPacketAtEd); } /************** @@ -277,34 +294,34 @@ LinkCheckTest::DoRun (void) class NetworkServerTestSuite : public TestSuite { -public: - NetworkServerTestSuite (); + public: + NetworkServerTestSuite(); }; -NetworkServerTestSuite::NetworkServerTestSuite () - : TestSuite ("network-server", UNIT) +NetworkServerTestSuite::NetworkServerTestSuite() + : TestSuite("network-server", UNIT) { - LogComponentEnable ("NetworkServerTestSuite", LOG_LEVEL_DEBUG); - - LogComponentEnable ("NetworkServer", LOG_LEVEL_ALL); - LogComponentEnable ("NetworkStatus", LOG_LEVEL_ALL); - LogComponentEnable ("NetworkScheduler", LOG_LEVEL_ALL); - LogComponentEnable ("NetworkController", LOG_LEVEL_ALL); - LogComponentEnable ("NetworkControllerComponent", LOG_LEVEL_ALL); - LogComponentEnable ("LoraNetDevice", LOG_LEVEL_ALL); - LogComponentEnable ("GatewayLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceLorawanMac", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceLoraPhy", LOG_LEVEL_ALL); - LogComponentEnable ("EndDeviceStatus", LOG_LEVEL_ALL); - - LogComponentEnableAll (LOG_PREFIX_FUNC); - LogComponentEnableAll (LOG_PREFIX_NODE); - LogComponentEnableAll (LOG_PREFIX_TIME); - - // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER - AddTestCase (new UplinkPacketTest, TestCase::QUICK); - AddTestCase (new DownlinkPacketTest, TestCase::QUICK); - AddTestCase (new LinkCheckTest, TestCase::QUICK); + LogComponentEnable("NetworkServerTestSuite", LOG_LEVEL_DEBUG); + + LogComponentEnable("NetworkServer", LOG_LEVEL_ALL); + LogComponentEnable("NetworkStatus", LOG_LEVEL_ALL); + LogComponentEnable("NetworkScheduler", LOG_LEVEL_ALL); + LogComponentEnable("NetworkController", LOG_LEVEL_ALL); + LogComponentEnable("NetworkControllerComponent", LOG_LEVEL_ALL); + LogComponentEnable("LoraNetDevice", LOG_LEVEL_ALL); + LogComponentEnable("GatewayLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceLorawanMac", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceLoraPhy", LOG_LEVEL_ALL); + LogComponentEnable("EndDeviceStatus", LOG_LEVEL_ALL); + + LogComponentEnableAll(LOG_PREFIX_FUNC); + LogComponentEnableAll(LOG_PREFIX_NODE); + LogComponentEnableAll(LOG_PREFIX_TIME); + + // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER + AddTestCase(new UplinkPacketTest, TestCase::QUICK); + AddTestCase(new DownlinkPacketTest, TestCase::QUICK); + AddTestCase(new LinkCheckTest, TestCase::QUICK); } // Do not forget to allocate an instance of this TestSuite diff --git a/test/network-status-test-suite.cc b/test/network-status-test-suite.cc index 26884c0a24..3f5902db3b 100644 --- a/test/network-status-test-suite.cc +++ b/test/network-status-test-suite.cc @@ -6,13 +6,14 @@ * - NetworkStatus * * Author: Davide Magrin -*/ + */ // Include headers of classes to test -#include "ns3/log.h" +#include "utilities.h" + #include "ns3/end-device-status.h" +#include "ns3/log.h" #include "ns3/network-status.h" -#include "utilities.h" // An essential include is test.h #include "ns3/test.h" @@ -20,7 +21,7 @@ using namespace ns3; using namespace lorawan; -NS_LOG_COMPONENT_DEFINE ("NetworkStatusTestSuite"); +NS_LOG_COMPONENT_DEFINE("NetworkStatusTestSuite"); ///////////////////////////// // EndDeviceStatus testing // @@ -28,34 +29,34 @@ NS_LOG_COMPONENT_DEFINE ("NetworkStatusTestSuite"); class EndDeviceStatusTest : public TestCase { -public: - EndDeviceStatusTest (); - virtual ~EndDeviceStatusTest (); + public: + EndDeviceStatusTest(); + virtual ~EndDeviceStatusTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -EndDeviceStatusTest::EndDeviceStatusTest () - : TestCase ("Verify correct behavior of the EndDeviceStatus object") +EndDeviceStatusTest::EndDeviceStatusTest() + : TestCase("Verify correct behavior of the EndDeviceStatus object") { } // Reminder that the test case should clean up after itself -EndDeviceStatusTest::~EndDeviceStatusTest () +EndDeviceStatusTest::~EndDeviceStatusTest() { } // This method is the pure virtual method from class TestCase that every // TestCase must implement void -EndDeviceStatusTest::DoRun (void) +EndDeviceStatusTest::DoRun(void) { - NS_LOG_DEBUG ("EndDeviceStatusTest"); + NS_LOG_DEBUG("EndDeviceStatusTest"); - // Create an EndDeviceStatus object - EndDeviceStatus eds = EndDeviceStatus (); + // Create an EndDeviceStatus object + EndDeviceStatus eds = EndDeviceStatus(); } ///////////////////////////// @@ -64,44 +65,43 @@ EndDeviceStatusTest::DoRun (void) class NetworkStatusTest : public TestCase { -public: - NetworkStatusTest (); - virtual ~NetworkStatusTest (); + public: + NetworkStatusTest(); + virtual ~NetworkStatusTest(); -private: - virtual void DoRun (void); + private: + virtual void DoRun(void); }; // Add some help text to this case to describe what it is intended to test -NetworkStatusTest::NetworkStatusTest () - : TestCase ("Verify correct behavior of the NetworkStatus object") +NetworkStatusTest::NetworkStatusTest() + : TestCase("Verify correct behavior of the NetworkStatus object") { } // Reminder that the test case should clean up after itself -NetworkStatusTest::~NetworkStatusTest () +NetworkStatusTest::~NetworkStatusTest() { } - // This method is the pure virtual method from class TestCase that every // TestCase must implement void -NetworkStatusTest::DoRun (void) +NetworkStatusTest::DoRun(void) { - NS_LOG_DEBUG ("NetworkStatusTest"); + NS_LOG_DEBUG("NetworkStatusTest"); - // Create a NetworkStatus object - NetworkStatus ns = NetworkStatus (); + // Create a NetworkStatus object + NetworkStatus ns = NetworkStatus(); - // Create a bunch of actual devices - NetworkComponents components = InitializeNetwork (1, 1); + // Create a bunch of actual devices + NetworkComponents components = InitializeNetwork(1, 1); - Ptr channel = components.channel; - NodeContainer endDevices = components.endDevices; - NodeContainer gateways = components.gateways; + Ptr channel = components.channel; + NodeContainer endDevices = components.endDevices; + NodeContainer gateways = components.gateways; - ns.AddNode (GetMacLayerFromNode (endDevices.Get (0))); + ns.AddNode(GetMacLayerFromNode(endDevices.Get(0))); } /************** @@ -114,17 +114,17 @@ NetworkStatusTest::DoRun (void) class NetworkStatusTestSuite : public TestSuite { -public: - NetworkStatusTestSuite (); + public: + NetworkStatusTestSuite(); }; -NetworkStatusTestSuite::NetworkStatusTestSuite () - : TestSuite ("network-status", UNIT) +NetworkStatusTestSuite::NetworkStatusTestSuite() + : TestSuite("network-status", UNIT) { - LogComponentEnable ("NetworkStatusTestSuite", LOG_LEVEL_DEBUG); - // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER - AddTestCase (new EndDeviceStatusTest, TestCase::QUICK); - AddTestCase (new NetworkStatusTest, TestCase::QUICK); + LogComponentEnable("NetworkStatusTestSuite", LOG_LEVEL_DEBUG); + // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER + AddTestCase(new EndDeviceStatusTest, TestCase::QUICK); + AddTestCase(new NetworkStatusTest, TestCase::QUICK); } // Do not forget to allocate an instance of this TestSuite diff --git a/test/utilities.cc b/test/utilities.cc index 9b5f1df834..c43ea46804 100644 --- a/test/utilities.cc +++ b/test/utilities.cc @@ -1,120 +1,123 @@ #include "utilities.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ Ptr -CreateChannel (void) +CreateChannel(void) { - // Create the lora channel object - Ptr loss = CreateObject (); - loss->SetPathLossExponent (3.76); - loss->SetReference (1, 7.7); + // Create the lora channel object + Ptr loss = CreateObject(); + loss->SetPathLossExponent(3.76); + loss->SetReference(1, 7.7); - Ptr delay = CreateObject (); + Ptr delay = CreateObject(); - return CreateObject (loss, delay); + return CreateObject(loss, delay); } NodeContainer -CreateEndDevices (int nDevices, MobilityHelper mobility, Ptr channel) +CreateEndDevices(int nDevices, MobilityHelper mobility, Ptr channel) { - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); - // Create the LoraHelper - LoraHelper helper = LoraHelper (); + // Create the LoraHelper + LoraHelper helper = LoraHelper(); - // Create a set of nodes - NodeContainer endDevices; - endDevices.Create (nDevices); + // Create a set of nodes + NodeContainer endDevices; + endDevices.Create(nDevices); - // Assign a mobility model to the node - mobility.Install (endDevices); + // Assign a mobility model to the node + mobility.Install(endDevices); - // Create the LoraNetDevices of the end devices - phyHelper.SetDeviceType (LoraPhyHelper::ED); - macHelper.SetDeviceType (LorawanMacHelper::ED_A); - helper.Install (phyHelper, macHelper, endDevices); + // Create the LoraNetDevices of the end devices + phyHelper.SetDeviceType(LoraPhyHelper::ED); + macHelper.SetDeviceType(LorawanMacHelper::ED_A); + helper.Install(phyHelper, macHelper, endDevices); - return endDevices; + return endDevices; } NodeContainer -CreateGateways (int nGateways, MobilityHelper mobility, Ptr channel) +CreateGateways(int nGateways, MobilityHelper mobility, Ptr channel) { - // Create the LoraPhyHelper - LoraPhyHelper phyHelper = LoraPhyHelper (); - phyHelper.SetChannel (channel); + // Create the LoraPhyHelper + LoraPhyHelper phyHelper = LoraPhyHelper(); + phyHelper.SetChannel(channel); - // Create the LorawanMacHelper - LorawanMacHelper macHelper = LorawanMacHelper (); + // Create the LorawanMacHelper + LorawanMacHelper macHelper = LorawanMacHelper(); - // Create the LoraHelper - LoraHelper helper = LoraHelper (); + // Create the LoraHelper + LoraHelper helper = LoraHelper(); - // Create the gateways - NodeContainer gateways; - gateways.Create (nGateways); + // Create the gateways + NodeContainer gateways; + gateways.Create(nGateways); - mobility.Install (gateways); + mobility.Install(gateways); - // Create a netdevice for each gateway - phyHelper.SetDeviceType (LoraPhyHelper::GW); - macHelper.SetDeviceType (LorawanMacHelper::GW); - helper.Install (phyHelper, macHelper, gateways); + // Create a netdevice for each gateway + phyHelper.SetDeviceType(LoraPhyHelper::GW); + macHelper.SetDeviceType(LorawanMacHelper::GW); + helper.Install(phyHelper, macHelper, gateways); - return gateways; + return gateways; } Ptr -CreateNetworkServer (NodeContainer endDevices, NodeContainer gateways) +CreateNetworkServer(NodeContainer endDevices, NodeContainer gateways) { - // Create the NetworkServer - NetworkServerHelper networkServerHelper = NetworkServerHelper (); - networkServerHelper.SetEndDevices (endDevices); - networkServerHelper.SetGateways (gateways); - Ptr nsNode = CreateObject (); - networkServerHelper.Install (nsNode); // This connects NS and GWs - - // Install a forwarder on the gateways - ForwarderHelper forwarderHelper; - forwarderHelper.Install (gateways); - - return nsNode; + // Create the NetworkServer + NetworkServerHelper networkServerHelper = NetworkServerHelper(); + networkServerHelper.SetEndDevices(endDevices); + networkServerHelper.SetGateways(gateways); + Ptr nsNode = CreateObject(); + networkServerHelper.Install(nsNode); // This connects NS and GWs + + // Install a forwarder on the gateways + ForwarderHelper forwarderHelper; + forwarderHelper.Install(gateways); + + return nsNode; } NetworkComponents -InitializeNetwork (int nDevices, int nGateways) +InitializeNetwork(int nDevices, int nGateways) { - // This function sets up a network with some devices and some gateways, and - // returns the created nodes through a NetworkComponents struct. + // This function sets up a network with some devices and some gateways, and + // returns the created nodes through a NetworkComponents struct. - Ptr channel = CreateChannel (); + Ptr channel = CreateChannel(); - MobilityHelper mobility; - mobility.SetPositionAllocator ("ns3::UniformDiscPositionAllocator", - "rho", DoubleValue (1000), - "X", DoubleValue (0.0), - "Y", DoubleValue (0.0)); - mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + MobilityHelper mobility; + mobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator", + "rho", + DoubleValue(1000), + "X", + DoubleValue(0.0), + "Y", + DoubleValue(0.0)); + mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); - NodeContainer endDevices = CreateEndDevices (nDevices, mobility, channel); + NodeContainer endDevices = CreateEndDevices(nDevices, mobility, channel); - NodeContainer gateways = CreateGateways (nGateways, mobility, channel); + NodeContainer gateways = CreateGateways(nGateways, mobility, channel); - LorawanMacHelper ().SetSpreadingFactorsUp (endDevices, gateways, channel); + LorawanMacHelper().SetSpreadingFactorsUp(endDevices, gateways, channel); - Ptr nsNode = CreateNetworkServer (endDevices, gateways); + Ptr nsNode = CreateNetworkServer(endDevices, gateways); - return { - channel, endDevices, gateways, nsNode - }; + return {channel, endDevices, gateways, nsNode}; } -} -} +} // namespace lorawan +} // namespace ns3 diff --git a/test/utilities.h b/test/utilities.h index 51db10bec0..c383e033a1 100644 --- a/test/utilities.h +++ b/test/utilities.h @@ -20,43 +20,42 @@ #ifndef TEST_UTILITIES_H #define TEST_UTILITIES_H +#include "ns3/forwarder-helper.h" #include "ns3/lora-helper.h" #include "ns3/mobility-helper.h" -#include "ns3/position-allocator.h" -#include "ns3/forwarder-helper.h" #include "ns3/network-server-helper.h" +#include "ns3/position-allocator.h" -namespace ns3 { -namespace lorawan { +namespace ns3 +{ +namespace lorawan +{ struct NetworkComponents { - Ptr channel; - NodeContainer endDevices; - NodeContainer gateways; - Ptr nsNode; + Ptr channel; + NodeContainer endDevices; + NodeContainer gateways; + Ptr nsNode; }; -Ptr CreateChannel (void); +Ptr CreateChannel(void); -NodeContainer CreateEndDevices (int nDevices, MobilityHelper mobility, - Ptr channel); +NodeContainer CreateEndDevices(int nDevices, MobilityHelper mobility, Ptr channel); -NodeContainer CreateGateways (int nGateways, MobilityHelper mobility, - Ptr channel); +NodeContainer CreateGateways(int nGateways, MobilityHelper mobility, Ptr channel); -Ptr CreateNetworkServer (NodeContainer endDevices, - NodeContainer gateways); +Ptr CreateNetworkServer(NodeContainer endDevices, NodeContainer gateways); template Ptr -GetMacLayerFromNode (Ptr n) +GetMacLayerFromNode(Ptr n) { - return n->GetDevice (0)->GetObject ()->GetMac ()->GetObject (); + return n->GetDevice(0)->GetObject()->GetMac()->GetObject(); } -NetworkComponents InitializeNetwork (int nDevices, int nGateways); -} +NetworkComponents InitializeNetwork(int nDevices, int nGateways); +} // namespace lorawan -} +} // namespace ns3 #endif