From 3d4b05bef0bdb2745fd31d9f5e2aaaa7f9490789 Mon Sep 17 00:00:00 2001 From: Alessio Bugetti Date: Wed, 11 Sep 2024 01:12:02 +0200 Subject: [PATCH] lr-wpan: (fixes #1130) Delay channel creation and add methods to set propagation loss and delay models in LrWpanHelper - Delay channel creation by moving it to Install() - Add SetPropagationDelayModel() and AddPropagationLossModel() methods to allow setting propagation loss and delay models in LrWpanHelper - Update all examples that use LrWpanHelper to reflect these changes --- examples/ipv6/wsn-ping6.cc | 2 + src/lr-wpan/examples/lr-wpan-bootstrap.cc | 12 +--- src/lr-wpan/examples/lr-wpan-data.cc | 51 ++++++++------ src/lr-wpan/examples/lr-wpan-mlme.cc | 27 +++----- src/lr-wpan/helper/lr-wpan-helper.cc | 67 ++++++++++++------- src/lr-wpan/helper/lr-wpan-helper.h | 66 ++++++++++++++---- src/lr-wpan/test/lr-wpan-ack-test.cc | 28 ++------ .../examples/example-ping-lr-wpan-beacon.cc | 2 + .../example-ping-lr-wpan-mesh-under.cc | 2 + .../examples/example-ping-lr-wpan.cc | 2 + 10 files changed, 151 insertions(+), 108 deletions(-) diff --git a/examples/ipv6/wsn-ping6.cc b/examples/ipv6/wsn-ping6.cc index d2ceb0215..d879f4f93 100644 --- a/examples/ipv6/wsn-ping6.cc +++ b/examples/ipv6/wsn-ping6.cc @@ -74,6 +74,8 @@ main(int argc, char** argv) NS_LOG_INFO("Create channels."); LrWpanHelper lrWpanHelper; + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); // Add and install the LrWpanNetDevice for each node // lrWpanHelper.EnableLogComponents(); NetDeviceContainer devContainer = lrWpanHelper.Install(nodes); diff --git a/src/lr-wpan/examples/lr-wpan-bootstrap.cc b/src/lr-wpan/examples/lr-wpan-bootstrap.cc index 14c8fa63b..2975f8d3f 100644 --- a/src/lr-wpan/examples/lr-wpan-bootstrap.cc +++ b/src/lr-wpan/examples/lr-wpan-bootstrap.cc @@ -358,17 +358,9 @@ main(int argc, char* argv[]) mobility.SetPositionAllocator(listPositionAlloc); mobility.Install(coordinators); - Ptr channel = CreateObject(); - Ptr propModel = - CreateObject(); - Ptr delayModel = - CreateObject(); - - channel->AddPropagationLossModel(propModel); - channel->SetPropagationDelayModel(delayModel); - LrWpanHelper lrWpanHelper; - lrWpanHelper.SetChannel(channel); + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); NetDeviceContainer lrwpanDevices = lrWpanHelper.Install(nodes); lrwpanDevices.Add(lrWpanHelper.Install(coordinators)); diff --git a/src/lr-wpan/examples/lr-wpan-data.cc b/src/lr-wpan/examples/lr-wpan-data.cc index 1892f2aba..b8bff2e44 100644 --- a/src/lr-wpan/examples/lr-wpan-data.cc +++ b/src/lr-wpan/examples/lr-wpan-data.cc @@ -80,10 +80,11 @@ main(int argc, char* argv[]) cmd.Parse(argc, argv); - LrWpanHelper lrWpanHelper; if (verbose) { - lrWpanHelper.EnableLogComponents(); + LogComponentEnableAll(LogLevel(LOG_PREFIX_TIME | LOG_PREFIX_FUNC)); + LogComponentEnable("LrWpanPhy", LOG_LEVEL_ALL); + LogComponentEnable("LrWpanMac", LOG_LEVEL_ALL); } // Enable calculation of FCS in the trailers. Only necessary when interacting with real devices @@ -96,19 +97,6 @@ main(int argc, char* argv[]) Ptr dev0 = CreateObject(); Ptr dev1 = CreateObject(); - if (!extended) - { - dev0->SetAddress(Mac16Address("00:01")); - dev1->SetAddress(Mac16Address("00:02")); - } - else - { - Ptr mac0 = dev0->GetMac(); - Ptr mac1 = dev1->GetMac(); - mac0->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:01")); - mac1->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:02")); - } - // Each device must be attached to the same channel Ptr channel = CreateObject(); Ptr propModel = @@ -125,6 +113,33 @@ main(int argc, char* argv[]) n0->AddDevice(dev0); n1->AddDevice(dev1); + // Note: This setup, which has been done manually here, can be simplified using the LrWpanHelper + // class. The LrWpanHelper can be used to set up the propagation loss and delay models in many + // devices in a simpler way. The following is an equivalent, simplified setup: + // + // LrWpanHelper lrWpanHelper; + // lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + // lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); + // NodeContainer nodes; + // nodes.Create(2); + // NetDeviceContainer devices = lrWpanHelper.Install(nodes); + // Ptr dev0 = devices.Get(0)->GetObject(); + // Ptr dev1 = devices.Get(1)->GetObject(); + + // Set 16-bit short addresses if extended is false, otherwise use 64-bit extended addresses + if (!extended) + { + dev0->SetAddress(Mac16Address("00:01")); + dev1->SetAddress(Mac16Address("00:02")); + } + else + { + Ptr mac0 = dev0->GetMac(); + Ptr mac1 = dev1->GetMac(); + mac0->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:01")); + mac1->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:02")); + } + // Trace state changes in the phy dev0->GetPhy()->TraceConnect("TrxState", std::string("phy0"), @@ -159,12 +174,6 @@ main(int argc, char* argv[]) cb3 = MakeCallback(&DataIndication); dev1->GetMac()->SetMcpsDataIndicationCallback(cb3); - // Tracing - lrWpanHelper.EnablePcapAll(std::string("lr-wpan-data"), true); - AsciiTraceHelper ascii; - Ptr stream = ascii.CreateFileStream("lr-wpan-data.tr"); - lrWpanHelper.EnableAsciiAll(stream); - // The below should trigger two callbacks when end-to-end data is working // 1) DataConfirm callback is called // 2) DataIndication callback is called with value of 50 diff --git a/src/lr-wpan/examples/lr-wpan-mlme.cc b/src/lr-wpan/examples/lr-wpan-mlme.cc index aca7d3624..10a10df04 100644 --- a/src/lr-wpan/examples/lr-wpan-mlme.cc +++ b/src/lr-wpan/examples/lr-wpan-mlme.cc @@ -87,29 +87,20 @@ main(int argc, char* argv[]) LrWpanHelper lrWpanHelper; // Create 2 nodes, and a NetDevice for each one - Ptr n0 = CreateObject(); - Ptr n1 = CreateObject(); - Ptr dev0 = CreateObject(); - Ptr dev1 = CreateObject(); + NodeContainer nodes; + nodes.Create(2); + + // Use LrWpanHelper to create devices and assign them to nodes + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); + NetDeviceContainer devices = lrWpanHelper.Install(nodes); + Ptr dev0 = devices.Get(0)->GetObject(); + Ptr dev1 = devices.Get(1)->GetObject(); dev0->SetAddress(Mac16Address("00:01")); dev1->SetAddress(Mac16Address("00:02")); - Ptr channel = CreateObject(); - Ptr propModel = - CreateObject(); - Ptr delayModel = - CreateObject(); - channel->AddPropagationLossModel(propModel); - channel->SetPropagationDelayModel(delayModel); - - dev0->SetChannel(channel); - dev1->SetChannel(channel); - - n0->AddDevice(dev0); - n1->AddDevice(dev1); - ///////////////// Mobility /////////////////////// Ptr sender0Mobility = CreateObject(); diff --git a/src/lr-wpan/helper/lr-wpan-helper.cc b/src/lr-wpan/helper/lr-wpan-helper.cc index 90a2d23e2..1eb20cc81 100644 --- a/src/lr-wpan/helper/lr-wpan-helper.cc +++ b/src/lr-wpan/helper/lr-wpan-helper.cc @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include namespace ns3 @@ -53,34 +51,12 @@ AsciiLrWpanMacTransmitSinkWithoutContext(Ptr stream, Ptr(); - - Ptr lossModel = - CreateObject(); - m_channel->AddPropagationLossModel(lossModel); - - Ptr delayModel = - CreateObject(); - m_channel->SetPropagationDelayModel(delayModel); + m_useMultiModelSpectrumChannel = false; } LrWpanHelper::LrWpanHelper(bool useMultiModelSpectrumChannel) { - if (useMultiModelSpectrumChannel) - { - m_channel = CreateObject(); - } - else - { - m_channel = CreateObject(); - } - Ptr lossModel = - CreateObject(); - m_channel->AddPropagationLossModel(lossModel); - - Ptr delayModel = - CreateObject(); - m_channel->SetPropagationDelayModel(delayModel); + m_useMultiModelSpectrumChannel = useMultiModelSpectrumChannel; } LrWpanHelper::~LrWpanHelper() @@ -167,6 +143,45 @@ LrWpanHelper::AddMobility(Ptr phy, Ptr m) NetDeviceContainer LrWpanHelper::Install(NodeContainer c) { + if (!m_channel) + { + if (m_useMultiModelSpectrumChannel) + { + m_channel = CreateObject(); + } + else + { + m_channel = CreateObject(); + } + if (!m_propagationDelay.IsTypeIdSet()) + { + SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + } + if (m_propagationLoss.empty()) + { + AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); + } + + for (auto i = m_propagationLoss.begin(); i != m_propagationLoss.end(); ++i) + { + Ptr cur = (*i).Create(); + m_channel->AddPropagationLossModel(cur); + } + Ptr delay = m_propagationDelay.Create(); + m_channel->SetPropagationDelayModel(delay); + } + else + { + if (!m_channel->GetPropagationDelayModel()) + { + NS_FATAL_ERROR("No propagation delay model added to the channel"); + } + if (!m_channel->GetPropagationLossModel()) + { + NS_FATAL_ERROR("No propagation loss model added to the channel"); + } + } + NetDeviceContainer devices; for (auto i = c.Begin(); i != c.End(); i++) { diff --git a/src/lr-wpan/helper/lr-wpan-helper.h b/src/lr-wpan/helper/lr-wpan-helper.h index 23c3ac949..8393ba6e6 100644 --- a/src/lr-wpan/helper/lr-wpan-helper.h +++ b/src/lr-wpan/helper/lr-wpan-helper.h @@ -39,23 +39,14 @@ class LrWpanHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevic { public: /** - * \brief Create a LrWpan helper in an empty state. By default, a - * SingleModelSpectrumChannel is created, with a - * LogDistancePropagationLossModel and a ConstantSpeedPropagationDelayModel. - * - * To change the channel type, loss model, or delay model, the Get/Set - * Channel methods may be used. + * \brief Create a LrWpan helper in an empty state. */ LrWpanHelper(); /** - * \brief Create a LrWpan helper in an empty state with either a - * SingleModelSpectrumChannel or a MultiModelSpectrumChannel. + * \brief Create a LrWpan helper in an empty state. * \param useMultiModelSpectrumChannel use a MultiModelSpectrumChannel if true, a * SingleModelSpectrumChannel otherwise - * - * A LogDistancePropagationLossModel and a - * ConstantSpeedPropagationDelayModel are added to the channel. */ LrWpanHelper(bool useMultiModelSpectrumChannel); @@ -83,6 +74,26 @@ class LrWpanHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevic */ void SetChannel(std::string channelName); + /** + * \tparam Ts \deduced Argument types + * \param name the name of the model to set + * \param [in] args Name and AttributeValue pairs to set. + * + * Add a propagation loss model to the set of currently-configured loss models. + */ + template + void AddPropagationLossModel(std::string name, Ts&&... args); + + /** + * \tparam Ts \deduced Argument types + * \param name the name of the model to set + * \param [in] args Name and AttributeValue pairs to set. + * + * Configure a propagation delay for this channel. + */ + template + void SetPropagationDelayModel(std::string name, Ts&&... args); + /** * \brief Add mobility model to a physical device * \param phy the physical device @@ -92,6 +103,16 @@ class LrWpanHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevic /** * \brief Install a LrWpanNetDevice and the associated structures (e.g., channel) in the nodes. + * + * If the channel is not already initialized, it will be created as either a + * SingleModelSpectrumChannel or a MultiModelSpectrumChannel, depending on the + * useMultiModelSpectrumChannel flag. Additionally, a ConstantSpeedPropagationDelayModel will be + * set as the default delay model if no delay model is specified, and a + * LogDistancePropagationLossModel will be added to the channel if no propagation loss models + * are defined. + * + * If the channel is already initialized but lacks either a PropagationDelayModel or a + * PropagationLossModel, an error will be raised. * \param c a set of nodes * \returns A container holding the added net devices. */ @@ -182,9 +203,30 @@ class LrWpanHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevic bool explicitFilename) override; private: - Ptr m_channel; //!< channel to be used for the devices + Ptr m_channel; //!< channel to be used for the devices + bool m_useMultiModelSpectrumChannel; //!< indicates whether a MultiModelSpectrumChannel is used + std::vector m_propagationLoss; ///< vector of propagation loss models + ObjectFactory m_propagationDelay; ///< propagation delay model }; +/*************************************************************** + * Implementation of the templates declared above. + ***************************************************************/ + +template +void +LrWpanHelper::AddPropagationLossModel(std::string name, Ts&&... args) +{ + m_propagationLoss.push_back(ObjectFactory(name, std::forward(args)...)); +} + +template +void +LrWpanHelper::SetPropagationDelayModel(std::string name, Ts&&... args) +{ + m_propagationDelay = ObjectFactory(name, std::forward(args)...); +} + } // namespace ns3 #endif /* LR_WPAN_HELPER_H */ diff --git a/src/lr-wpan/test/lr-wpan-ack-test.cc b/src/lr-wpan/test/lr-wpan-ack-test.cc index 6f3596f2a..d6c4ea302 100644 --- a/src/lr-wpan/test/lr-wpan-ack-test.cc +++ b/src/lr-wpan/test/lr-wpan-ack-test.cc @@ -181,11 +181,13 @@ LrWpanAckTestCase::DoRun() std::string asciiPrefix; // Create 2 nodes, and a NetDevice for each one - Ptr n0 = CreateObject(); - Ptr n1 = CreateObject(); - - m_dev0 = CreateObject(); - m_dev1 = CreateObject(); + NodeContainer nodes; + nodes.Create(2); + helper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + helper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); + NetDeviceContainer devices = helper.Install(nodes); + m_dev0 = devices.Get(0)->GetObject(); + m_dev1 = devices.Get(1)->GetObject(); // Make random variable stream assignment deterministic m_dev0->AssignStreams(0); @@ -198,22 +200,6 @@ LrWpanAckTestCase::DoRun() m_dev0->GetMac()->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:01")); m_dev1->GetMac()->SetExtendedAddress(Mac64Address("00:00:00:00:00:00:00:02")); - // Each device must be attached to the same channel - Ptr channel = CreateObject(); - Ptr propModel = - CreateObject(); - Ptr delayModel = - CreateObject(); - channel->AddPropagationLossModel(propModel); - channel->SetPropagationDelayModel(delayModel); - - m_dev0->SetChannel(channel); - m_dev1->SetChannel(channel); - - // To complete configuration, a LrWpanNetDevice must be added to a node - n0->AddDevice(m_dev0); - n1->AddDevice(m_dev1); - Ptr sender0Mobility = CreateObject(); sender0Mobility->SetPosition(Vector(0, 0, 0)); diff --git a/src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc b/src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc index f1916520f..437dbe35d 100644 --- a/src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc +++ b/src/sixlowpan/examples/example-ping-lr-wpan-beacon.cc @@ -72,6 +72,8 @@ main(int argc, char** argv) mobility.Install(nodes); LrWpanHelper lrWpanHelper; + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); // Add and install the LrWpanNetDevice for each node NetDeviceContainer lrwpanDevices = lrWpanHelper.Install(nodes); diff --git a/src/sixlowpan/examples/example-ping-lr-wpan-mesh-under.cc b/src/sixlowpan/examples/example-ping-lr-wpan-mesh-under.cc index 6e50a0531..e08a400c3 100644 --- a/src/sixlowpan/examples/example-ping-lr-wpan-mesh-under.cc +++ b/src/sixlowpan/examples/example-ping-lr-wpan-mesh-under.cc @@ -67,6 +67,8 @@ main(int argc, char** argv) mobility.Install(wsnNodes); LrWpanHelper lrWpanHelper; + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); // Add and install the LrWpanNetDevice for each node NetDeviceContainer lrwpanDevices = lrWpanHelper.Install(wsnNodes); diff --git a/src/sixlowpan/examples/example-ping-lr-wpan.cc b/src/sixlowpan/examples/example-ping-lr-wpan.cc index a52f4ca1e..9099c93cf 100644 --- a/src/sixlowpan/examples/example-ping-lr-wpan.cc +++ b/src/sixlowpan/examples/example-ping-lr-wpan.cc @@ -67,6 +67,8 @@ main(int argc, char** argv) mobility.Install(nodes); LrWpanHelper lrWpanHelper; + lrWpanHelper.SetPropagationDelayModel("ns3::ConstantSpeedPropagationDelayModel"); + lrWpanHelper.AddPropagationLossModel("ns3::LogDistancePropagationLossModel"); // Add and install the LrWpanNetDevice for each node NetDeviceContainer lrwpanDevices = lrWpanHelper.Install(nodes);