diff --git a/CHANGES.md b/CHANGES.md index 1941d5f9ee..a93cdf56a2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,7 @@ This file is a best-effort approach to solving this issue; we will do our best b * (applications) Deprecated attributes `RemoteAddress` and `RemotePort` in UdpClient, UdpTraceClient and UdpEchoClient. They have been combined into a single `Remote` attribute. * (applications) Deprecated attributes `ThreeGppHttpClient::RemoteServerAddress` and `ThreeGppHttpClient::RemoteServerPort`. They have been combined into a single `ThreeGppHttpClient::Remote` attribute. +* (lr-wpan) ``LrWpanMac`` is now also aggregated to ``LrWpanNetDevice``. * (stats) Deprecated ns3::NaN and ns3::isNaN to use std::nan and std::isnan in their place * (wifi) Added a new **ProtectedIfResponded** attribute to `FrameExchangeManager` to disable RTS/CTS protection for stations that have already responded to a frame requiring acknowledgment in the same TXOP, even if such frame had not been protected by RTS/CTS. The default value is true, even though it represents a change with respect to the previous behavior, because it is likely a more realistic choice. * (wifi) Deprecated setters/getters of the {Ht,Vht,He}Configuration classes that trivially set/get member variables, which have been made public and hence accessible to users. diff --git a/src/lr-wpan/doc/lr-wpan.rst b/src/lr-wpan/doc/lr-wpan.rst index a617097569..fe59835197 100644 --- a/src/lr-wpan/doc/lr-wpan.rst +++ b/src/lr-wpan/doc/lr-wpan.rst @@ -8,12 +8,12 @@ IEEE 802.15.4: Low-Rate Wireless Personal Area Network (LR-WPAN) This chapter describes the implementation of |ns3| models for the low-rate, wireless personal area network (LR-WPAN) as specified by IEEE standard 802.15.4 (2003,2006,2011). The current emphasis is on direct transmissions running on both, -slotted and unslotted mode (CSMA/CA) of IEEE 802.15.4 operation for use in Zigbee and 6loWPAN networks. +slotted and unslotted mode (CSMA/CA) of IEEE 802.15.4 operation for use in Zigbee (TM) and 6loWPAN networks. Both beacon and non-beacon modes are supported as well as the bootstrap mechanism (scan and association). -In general, this document describes what is modeled and how it is modeled; the following section [Scope and -Limitations]() provides more details about what is not covered or what is missing in the model. +In general, this document describes what is modeled and how it is modeled; the following section Scope and +Limitations provides more details about what is not covered or what is missing in the model. The model is implemented into the ``src/lrwpan/`` folder. @@ -110,10 +110,13 @@ The PHY primitives currently supported by the |ns3| model are: For more information on primitives, See IEEE 802.15.4-2011, Table 8. -Although it is expected that other technology profiles (such as -6LoWPAN and ZigBee) will write their own NetDevice classes, a basic -``LrWpanNetDevice`` is provided, which encapsulates the common operations -of creating a generic LrWpan device and hooking things together. +In addition, this module provides a configuration for connecting various components. +The current design of the ``LrWpanNetDevice`` allows for the configuration of different instances of ``LrWpanMac``, which can only be set before the initialization of the NetDevice. +This design can be extended in the future to support other subclasses of ``LrWpanMacBase``, enabling the configuration of different types of MAC layers using the same ``LrWpanNetDevice``. + +The ``LrWpanNetDevice`` presented in this module is intended to be used with other technology profiles, such as the 6LoWPAN and ZigBee stack. + + Scope and Limitations @@ -226,18 +229,18 @@ The implemented |ns3| MAC layer supports scanning. Typically, a scanning request by an association request but these can be used independently. |ns3| IEEE 802.15.4 MAC layer supports 4 types of scanning: -* *Energy Detection (ED) Scan:* In an energy scan, a device or a coordinator scan a set number of channels looking for traces of energy. The maximum energy registered during a given amount of time is stored. Energy scan is typically used to measure the quality of a channel at any given time. For this reason, coordinators often use this scan before initiating a PAN on a channel. +* **Energy Detection (ED) Scan:** In an energy scan, a device or a coordinator scan a set number of channels looking for traces of energy. The maximum energy registered during a given amount of time is stored. Energy scan is typically used to measure the quality of a channel at any given time. For this reason, coordinators often use this scan before initiating a PAN on a channel. -* *Active Scan:* A device sends ``beacon request commands`` on a set number of channels looking for a PAN coordinator. The receiving coordinator must be configured on non-beacon mode. Coordinators on beacon-mode ignore these requests. The coordinators who accept the request, respond with a beacon. After an active scan take place, during the association process devices extract the information in the PAN descriptors from the collected beacons and based on this information (e.g. channel, LQI level), choose a coordinator to associate with. +* **Active Scan:** A device sends ``beacon request commands`` on a set number of channels looking for a PAN coordinator. The receiving coordinator must be configured on non-beacon mode. Coordinators on beacon-mode ignore these requests. The coordinators who accept the request, respond with a beacon. After an active scan take place, during the association process devices extract the information in the PAN descriptors from the collected beacons and based on this information (e.g. channel, LQI level), choose a coordinator to associate with. -* *Passive Scan:* In a passive scan, no ``beacon requests commands`` are sent. Devices scan a set number of channels looking for beacons currently being transmitted (coordinators in beacon-mode). Like in the active scan, the information from beacons is stored in PAN descriptors and used by the device to choose a coordinator to associate with. +* **Passive Scan:** In a passive scan, no ``beacon requests commands`` are sent. Devices scan a set number of channels looking for beacons currently being transmitted (coordinators in beacon-mode). Like in the active scan, the information from beacons is stored in PAN descriptors and used by the device to choose a coordinator to associate with. -* *Orphan Scan:* Orphan scan is used typically by device as a result of repeated communication failure attempts with a coordinator. In other words, an orphan scan represents the intent of a device to relocate its coordinator. In some situations, it can be used by devices higher layers to not only rejoin a network but also join a network for the first time. In an orphan scan, a device send a ``orphan notification command`` to a given list of channels. If a coordinator receives this notification, it responds to the device with a ``coordinator realignment command``. +* **Orphan Scan:** Orphan scan is used typically by device as a result of repeated communication failure attempts with a coordinator. In other words, an orphan scan represents the intent of a device to relocate its coordinator. In some situations, it can be used by devices higher layers to not only rejoin a network but also join a network for the first time. In an orphan scan, a device send a ``orphan notification command`` to a given list of channels. If a coordinator receives this notification, it responds to the device with a ``coordinator realignment command``. In active and passive scans, the link quality indicator (LQI) is the main parameter used to determine the optimal coordinator. LQI values range from 0 to 255. Where 255 is the highest quality link value and 0 the lowest. Typically, a link lower than 127 is considered a link with poor quality. -In LR-WPAN, association is used to join PANs. All devices in LR-WPAN must belong to a PAN to communicate. |ns3| uses a classic association procedure described in the standard. The standard also covers a more effective association procedure known as fast association (See IEEE 802.15.4-2015, fastA) but this association is currently not supported by |ns3|. Alternatively, |ns3| can do a "quick and dirty" association using either ```LrWpanHelper::AssociateToPan``` or ```LrWpanHelper::AssociateToBeaconPan```. These functions are used when a preset association can be done. For example, when the relationships between existing nodes and coordinators are known and can be set before the beginning of the simulation. In other situations, like in many networks in real deployments or in large networks, it is desirable that devices "associate themselves" with the best possible available coordinator candidates. This is a process known as bootstrap, and simulating this process makes it possible to demonstrate the kind of situations a node would face in which large networks to associate in real environment. +In LR-WPAN, association is used to join PANs. All devices in LR-WPAN must belong to a PAN to communicate. |ns3| uses a classic association procedure described in the standard. The standard also covers a more effective association procedure known as fast association (See IEEE 802.15.4-2015, fastA) but this association is currently not supported by |ns3|. Alternatively, |ns3| can do a "quick and dirty" association using either ```LrWpanHelper::AssociateToPan``` or ```LrWpanHelper::AssociateToBeaconPan```. These functions are used when a preset association can be done. For example, when the relationships between existing nodes and coordinators are known and can be set before the beginning of the simulation. In other situations, like in many networks in real deployments or in large networks, it is desirable that devices "associate themselves" with the best possible available coordinator candidates. This is a process known as bootstrap, and simulating this process makes it possible to demonstrate the kind of situations a node would face in which large networks to associate in real environment. Bootstrap (a.k.a. network initialization) is possible with a combination of scan and association MAC primitives. Details on the general process for this network initialization is described in the standard. Bootstrap is a complex process that not only requires the scanning networks, but also the exchange of command frames and the use of a pending transaction list (indirect transmissions) in the coordinator to store command frames. The following summarizes the whole process: @@ -250,8 +253,8 @@ Examples such as ``lr-wpan-bootstrap.cc`` demonstrate the whole bootstrap proce A key element to remember is that bootstrap have 2 objectives: -1- Enable devices to join a new formed network (associate). -2- Assign short addresses and PAN ID. +1. Enable devices to join a new formed network (associate). +2. Assign short addresses and PAN ID. Devices that have the short address ``FF:FF`` are not associated an cannot participate in any unicast communication in the network. Devices that have the short address ``FF:FE`` and have a valid PAN ID can communicate with other devices in the network using the diff --git a/src/lr-wpan/model/lr-wpan-mac.cc b/src/lr-wpan/model/lr-wpan-mac.cc index 58e20d94aa..bd380de625 100644 --- a/src/lr-wpan/model/lr-wpan-mac.cc +++ b/src/lr-wpan/model/lr-wpan-mac.cc @@ -252,11 +252,14 @@ LrWpanMac::LrWpanMac() LrWpanMac::~LrWpanMac() { + NS_LOG_FUNCTION(this); } void LrWpanMac::DoInitialize() { + NS_LOG_FUNCTION(this); + if (m_macRxOnWhenIdle) { m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON); @@ -272,6 +275,8 @@ LrWpanMac::DoInitialize() void LrWpanMac::DoDispose() { + NS_LOG_FUNCTION(this); + if (m_csmaCa) { m_csmaCa->Dispose(); @@ -291,6 +296,7 @@ LrWpanMac::DoDispose() } m_indTxQueue.clear(); + m_uniformVar = nullptr; m_phy = nullptr; m_mcpsDataConfirmCallback = MakeNullCallback(); m_mcpsDataIndicationCallback = MakeNullCallback>(); diff --git a/src/lr-wpan/model/lr-wpan-net-device.cc b/src/lr-wpan/model/lr-wpan-net-device.cc index e62b6084cb..2e4eb39f22 100644 --- a/src/lr-wpan/model/lr-wpan-net-device.cc +++ b/src/lr-wpan/model/lr-wpan-net-device.cc @@ -76,10 +76,10 @@ LrWpanNetDevice::LrWpanNetDevice() : m_configComplete(false) { NS_LOG_FUNCTION(this); - m_mac = CreateObject(); + m_phy = CreateObject(); m_csmaca = CreateObject(); - CompleteConfig(); + m_mac = CreateObject(); } LrWpanNetDevice::~LrWpanNetDevice() @@ -91,7 +91,6 @@ void LrWpanNetDevice::DoDispose() { NS_LOG_FUNCTION(this); - m_mac->Dispose(); m_phy->Dispose(); m_csmaca->Dispose(); m_phy = nullptr; @@ -106,19 +105,22 @@ void LrWpanNetDevice::DoInitialize() { NS_LOG_FUNCTION(this); - m_phy->Initialize(); - m_mac->Initialize(); + + AggregateObject(m_mac); + CompleteConfig(); + NetDevice::DoInitialize(); } void LrWpanNetDevice::CompleteConfig() { - NS_LOG_FUNCTION(this); if (!m_mac || !m_phy || !m_csmaca || !m_node || m_configComplete) { return; } + + NS_LOG_FUNCTION(this); m_mac->SetPhy(m_phy); m_mac->SetCsmaCa(m_csmaca); m_mac->SetMcpsDataIndicationCallback(MakeCallback(&LrWpanNetDevice::McpsDataIndication, this)); @@ -146,75 +148,68 @@ LrWpanNetDevice::CompleteConfig() void LrWpanNetDevice::SetMac(Ptr mac) { - NS_LOG_FUNCTION(this); + NS_ABORT_MSG_IF(LrWpanNetDevice::IsInitialized(), + "MAC layer cannot be set after initialization"); m_mac = mac; - CompleteConfig(); } void LrWpanNetDevice::SetPhy(Ptr phy) { - NS_LOG_FUNCTION(this); + NS_ABORT_MSG_IF(LrWpanNetDevice::IsInitialized(), + "PHY layer cannot be set after initialization"); m_phy = phy; - CompleteConfig(); } void LrWpanNetDevice::SetCsmaCa(Ptr csmaca) { - NS_LOG_FUNCTION(this); + NS_ABORT_MSG_IF(LrWpanNetDevice::IsInitialized(), "CSMA/CA cannot be set after initialization"); m_csmaca = csmaca; - CompleteConfig(); } void LrWpanNetDevice::SetChannel(Ptr channel) { - NS_LOG_FUNCTION(this << channel); + NS_ABORT_MSG_IF(LrWpanNetDevice::IsInitialized(), + "Spectrum channel cannot be set after initialization"); m_phy->SetChannel(channel); channel->AddRx(m_phy); - CompleteConfig(); } Ptr LrWpanNetDevice::GetMac() const { - // NS_LOG_FUNCTION (this); return m_mac; } Ptr LrWpanNetDevice::GetPhy() const { - NS_LOG_FUNCTION(this); return m_phy; } Ptr LrWpanNetDevice::GetCsmaCa() const { - NS_LOG_FUNCTION(this); return m_csmaca; } void LrWpanNetDevice::SetIfIndex(const uint32_t index) { - NS_LOG_FUNCTION(this << index); m_ifIndex = index; } uint32_t LrWpanNetDevice::GetIfIndex() const { - NS_LOG_FUNCTION(this); return m_ifIndex; } Ptr LrWpanNetDevice::GetChannel() const { - NS_LOG_FUNCTION(this); return m_phy->GetChannel(); } @@ -449,14 +444,12 @@ LrWpanNetDevice::SendFrom(Ptr packet, Ptr LrWpanNetDevice::GetNode() const { - NS_LOG_FUNCTION(this); return m_node; } void LrWpanNetDevice::SetNode(Ptr node) { - NS_LOG_FUNCTION(this); m_node = node; CompleteConfig(); } diff --git a/src/lr-wpan/test/lr-wpan-ifs-test.cc b/src/lr-wpan/test/lr-wpan-ifs-test.cc index 4cd18f07a0..625638a1a7 100644 --- a/src/lr-wpan/test/lr-wpan-ifs-test.cc +++ b/src/lr-wpan/test/lr-wpan-ifs-test.cc @@ -391,6 +391,20 @@ LrWpanDataIfsTestCase::DoRun() ////////////////////////////////////////////////////////////////////////////////// + // Disconnect traces to eliminate Valgrid errors + dev0->GetMac()->TraceDisconnectWithoutContext( + "IfsEnd", + MakeBoundCallback(&LrWpanDataIfsTestCase::IfsEnd, this, dev0)); + dev0->GetMac()->TraceDisconnectWithoutContext( + "MacRx", + MakeBoundCallback(&LrWpanDataIfsTestCase::DataReceivedDev0, this, dev0)); + dev0->GetPhy()->TraceDisconnectWithoutContext( + "PhyRxBegin", + MakeBoundCallback(&LrWpanDataIfsTestCase::PhyDataRxStart, this, dev0)); + dev1->GetMac()->TraceDisconnectWithoutContext( + "MacRx", + MakeBoundCallback(&LrWpanDataIfsTestCase::DataReceivedDev1, this, dev1)); + Simulator::Destroy(); } diff --git a/src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc b/src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc index 5f8f76168e..eda6de34df 100644 --- a/src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc +++ b/src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc @@ -324,6 +324,11 @@ LrWpanSlottedCsmacaTestCase::DoRun() (m_apBoundary + transactionTime), "Error, the transaction time is not the expected value"); + // Disconnect traces to eliminate valgrid errors + dev1->GetMac()->TraceDisconnectWithoutContext( + "MacIncSuperframeStatus", + MakeBoundCallback(&LrWpanSlottedCsmacaTestCase::IncomingSuperframeStatus, this, dev1)); + Simulator::Destroy(); } diff --git a/src/sixlowpan/test/sixlowpan-example-ping-lr-wpan.reflog b/src/sixlowpan/test/sixlowpan-example-ping-lr-wpan.reflog index 6410e8a5c9..8ca397be96 100644 --- a/src/sixlowpan/test/sixlowpan-example-ping-lr-wpan.reflog +++ b/src/sixlowpan/test/sixlowpan-example-ping-lr-wpan.reflog @@ -1,16 +1,16 @@ Device 0: pseudo-Mac-48 02:00:00:00:00:01, IPv6 Address 2001:2::ff:fe00:1 Device 1: pseudo-Mac-48 02:00:00:00:00:02, IPv6 Address 2001:2::ff:fe00:2 PING 2001:2::ff:fe00:2 - 16 bytes of data; 64 bytes including ICMP and IPv6 headers. -24 bytes from (2001:2::ff:fe00:2): icmp_seq=0 ttl=64 time=21.536 ms -24 bytes from (2001:2::ff:fe00:2): icmp_seq=1 ttl=64 time=9.312 ms -24 bytes from (2001:2::ff:fe00:2): icmp_seq=2 ttl=64 time=8.992 ms -24 bytes from (2001:2::ff:fe00:2): icmp_seq=3 ttl=64 time=9.952 ms -24 bytes from (2001:2::ff:fe00:2): icmp_seq=4 ttl=64 time=6.752 ms +24 bytes from (2001:2::ff:fe00:2): icmp_seq=0 ttl=64 time=21.216 ms +24 bytes from (2001:2::ff:fe00:2): icmp_seq=1 ttl=64 time=7.712 ms +24 bytes from (2001:2::ff:fe00:2): icmp_seq=2 ttl=64 time=7.712 ms +24 bytes from (2001:2::ff:fe00:2): icmp_seq=3 ttl=64 time=7.392 ms +24 bytes from (2001:2::ff:fe00:2): icmp_seq=4 ttl=64 time=10.592 ms --- 2001:2::ff:fe00:2 ping statistics --- -5 packets transmitted, 5 received, 0% packet loss, time 4006ms -rtt min/avg/max/mdev = 6/10.6/21/5.941 ms +5 packets transmitted, 5 received, 0% packet loss, time 4010ms +rtt min/avg/max/mdev = 7/10.4/21/6.066 ms NDISC Cache of node 0 at time +9s 2001:2::ff:fe00:2 dev 2 lladdr 00-06-02:00:00:00:00:02 REACHABLE NDISC Cache of node 1 at time +9s -2001:2::ff:fe00:1 dev 2 lladdr 00-06-02:00:00:00:00:01 REACHABLE \ No newline at end of file +2001:2::ff:fe00:1 dev 2 lladdr 00-06-02:00:00:00:00:01 REACHABLE diff --git a/src/zigbee/doc/zigbee.rst b/src/zigbee/doc/zigbee.rst index 428d9ad11a..507895a286 100644 --- a/src/zigbee/doc/zigbee.rst +++ b/src/zigbee/doc/zigbee.rst @@ -24,8 +24,12 @@ The source code for the new module lives in the directory ``src/zigbee``. Zigbee Stack Architecture in ns-3 -The Zigbee stack implementation is meant to be use on top of a |ns3| NetDevice with a valid lr-wpan MAC layer implementation. -This is in essence, a Netdevice that contains a ``LrWpanMacBase`` object which enforces a IEEE 802.15.4-2011 compliant MAC. +The Zigbee stack implementation is designed to operate on top of an existing |ns3| NetDevice that incorporates at least one object derived from ``LrWpanMacBase`` (which is compliant with IEEE 802.15.4-2011 MAC standards). +This device should have been previously aggregated, such as in the case of ``LrWpanNetDevice``. + +While other technologies like 6loWPAN can interact with the underlying MAC layer through general-purpose NetDevice interfaces, Zigbee has specific requirements that necessitate certain features from a lr-wpan MAC. +Consequently, the |ns3| Zigbee implementation directly accesses the aggregated ``LrWpanMacBase`` and interfaces with it accordingly. + The current scope of the project includes **only the NWK layer in the Zigbee stack**. However, the project can be later extended to support higher layers like the Application Sublayer (APS) and the Zigbee Cluster Library (ZCL). diff --git a/src/zigbee/helper/zigbee-helper.cc b/src/zigbee/helper/zigbee-helper.cc index d5fc89154d..ad06770def 100644 --- a/src/zigbee/helper/zigbee-helper.cc +++ b/src/zigbee/helper/zigbee-helper.cc @@ -10,7 +10,6 @@ #include "zigbee-helper.h" #include "ns3/log.h" -#include "ns3/lr-wpan-net-device.h" #include "ns3/names.h" #include "ns3/net-device.h" #include "ns3/node.h" @@ -45,16 +44,14 @@ ZigbeeHelper::Install(const NetDeviceContainer c) { Ptr device = c.Get(i); - NS_ASSERT_MSG(device != nullptr, "No LrWpanNetDevice found in the node " << i); - Ptr lrwpanNetdevice = DynamicCast(device); + NS_ASSERT_MSG(device, "NetDevice not found in the node " << i); - Ptr node = lrwpanNetdevice->GetNode(); - NS_LOG_LOGIC("**** Install Zigbee on node " << node->GetId()); + NS_LOG_LOGIC("Installing Zigbee on node " << device->GetNode()->GetId()); Ptr zigbeeStack = m_stackFactory.Create(); zigbeeStackContainer.Add(zigbeeStack); - node->AggregateObject(zigbeeStack); - zigbeeStack->SetLrWpanNetDevice(lrwpanNetdevice); + device->GetNode()->AggregateObject(zigbeeStack); + zigbeeStack->SetNetDevice(device); } return zigbeeStackContainer; } diff --git a/src/zigbee/model/zigbee-stack.cc b/src/zigbee/model/zigbee-stack.cc index dee4425c51..ba15a08563 100644 --- a/src/zigbee/model/zigbee-stack.cc +++ b/src/zigbee/model/zigbee-stack.cc @@ -29,7 +29,7 @@ TypeId ZigbeeStack::GetTypeId() { static TypeId tid = TypeId("ns3::zigbee::ZigbeeStack") - .SetParent() + .SetParent() .SetGroupName("Zigbee") .AddConstructor(); return tid; @@ -38,13 +38,10 @@ ZigbeeStack::GetTypeId() ZigbeeStack::ZigbeeStack() { NS_LOG_FUNCTION(this); - m_lrwpanNetDevice = nullptr; + m_nwk = CreateObject(); // TODO: Create APS layer here. - // m_aps = CreateObject (); - - // Automatically calls m_nwk initialize and dispose functions - AggregateObject(m_nwk); + // m_aps = CreateObject (); } ZigbeeStack::~ZigbeeStack() @@ -53,21 +50,36 @@ ZigbeeStack::~ZigbeeStack() } void -ZigbeeStack::CompleteConfig() +ZigbeeStack::DoDispose() { NS_LOG_FUNCTION(this); - // TODO: Set APS callback hooks with NWK when support for APS layer is added. - // For example: - // m_aps->SetNwk (m_nwk); - // m_nwk->SetNldeDataIndicationCallback (MakeCallback (&ZigbeeAps::NldeDataIndication, m_aps)); + m_netDevice = nullptr; + m_node = nullptr; + m_nwk = nullptr; + m_mac = nullptr; + Object::DoDispose(); +} - // Set NWK callback hooks with the MAC - if (m_lrwpanNetDevice != nullptr) - { - m_mac = m_lrwpanNetDevice->GetMac(); - } +void +ZigbeeStack::DoInitialize() +{ + NS_LOG_FUNCTION(this); + + AggregateObject(m_nwk); + + NS_ABORT_MSG_UNLESS(m_netDevice, + "Invalid NetDevice found when attempting to install ZigbeeStack"); + + // Make sure the NetDevice is previously initialized + // before using ZigbeeStack + m_netDevice->Initialize(); + m_mac = m_netDevice->GetObject(); + NS_ABORT_MSG_UNLESS(m_mac, + "No valid LrWpanMacBase found in this NetDevice, cannot use ZigbeeStack"); + + // Set NWK callback hooks with the MAC m_nwk->SetMac(m_mac); m_mac->SetMcpsDataIndicationCallback(MakeCallback(&ZigbeeNwk::McpsDataIndication, m_nwk)); m_mac->SetMlmeOrphanIndicationCallback(MakeCallback(&ZigbeeNwk::MlmeOrphanIndication, m_nwk)); @@ -87,57 +99,44 @@ ZigbeeStack::CompleteConfig() // Obtain Extended address as soon as NWK is set to begin operations m_mac->MlmeGetRequest(MacPibAttributeIdentifier::macExtendedAddress); -} -void -ZigbeeStack::DoDispose() -{ - NS_LOG_FUNCTION(this); - - m_lrwpanNetDevice = nullptr; - m_node = nullptr; - m_nwk = nullptr; - m_mac = nullptr; - Object::DoDispose(); -} + // TODO: Set APS callback hooks with NWK when support for APS layer is added. + // For example: + // m_aps->SetNwk (m_nwk); + // m_nwk->SetNldeDataIndicationCallback (MakeCallback (&ZigbeeAps::NldeDataIndication, m_aps)); -void -ZigbeeStack::DoInitialize() -{ - NS_LOG_FUNCTION(this); Object::DoInitialize(); } Ptr ZigbeeStack::GetChannel() const { - NS_LOG_FUNCTION(this); - // TODO - // NS_ABORT_MSG_UNLESS(m_lrwpanNetDevice != 0, - // "Zigbee: can't find any lower-layer protocol " << m_lrwpanNetDevice); - return m_lrwpanNetDevice->GetChannel(); + return m_netDevice->GetChannel(); } Ptr ZigbeeStack::GetNode() const { - NS_LOG_FUNCTION(this); return m_node; } +Ptr +ZigbeeStack::GetNetDevice() const +{ + return m_netDevice; +} + void -ZigbeeStack::SetLrWpanNetDevice(Ptr lrwpanDevice) +ZigbeeStack::SetNetDevice(Ptr netDevice) { - NS_LOG_FUNCTION(this << lrwpanDevice); - m_lrwpanNetDevice = lrwpanDevice; - m_node = lrwpanDevice->GetNode(); - CompleteConfig(); + NS_LOG_FUNCTION(this << netDevice); + m_netDevice = netDevice; + m_node = m_netDevice->GetNode(); } Ptr ZigbeeStack::GetNwk() const { - NS_LOG_FUNCTION(this); return m_nwk; } @@ -145,8 +144,8 @@ void ZigbeeStack::SetNwk(Ptr nwk) { NS_LOG_FUNCTION(this); + NS_ABORT_MSG_IF(ZigbeeStack::IsInitialized(), "NWK layer cannot be set after initialization"); m_nwk = nwk; - CompleteConfig(); } } // namespace zigbee diff --git a/src/zigbee/model/zigbee-stack.h b/src/zigbee/model/zigbee-stack.h index 40775143c9..5231dd1953 100644 --- a/src/zigbee/model/zigbee-stack.h +++ b/src/zigbee/model/zigbee-stack.h @@ -51,16 +51,19 @@ class ZigbeeStack : public Object * @return the object TypeId */ static TypeId GetTypeId(); + /** * Default constructor */ ZigbeeStack(); ~ZigbeeStack() override; + /** * Get the Channel object of the underlying LrWpanNetDevice * @return The LrWpanNetDevice Channel Object */ Ptr GetChannel() const; + /** * Get the node currently using this ZigbeeStack. * @return The reference to the node object using this ZigbeeStack. @@ -73,26 +76,29 @@ class ZigbeeStack : public Object * @return the NWK object */ Ptr GetNwk() const; + /** * Set the NWK layer used by this ZigbeeStack. * * @param nwk The NWK layer object */ void SetNwk(Ptr nwk); + /** - * Returns a smart pointer to the underlying LrWpanNetDevice. + * Returns a smart pointer to the underlying NetDevice. * - * @return A smart pointer to the underlying LrWpanNetDevice. + * @return A smart pointer to the underlying NetDevice. */ - Ptr GetLrWpanNetDevice() const; + Ptr GetNetDevice() const; + /** - * Setup Zigbee to be the next set of higher layers for the specified LrWpanNetDevice. - * All the packets incoming and outgoing from the LrWpanNetDevice will be - * processed ZigbeeNetDevice. + * Setup Zigbee to be the next set of higher layers for the specified NetDevice. + * All the packets incoming and outgoing from the NetDevice will be + * processed by ZigbeeStack. * - * @param [in] lrwpanDevice A smart pointer to the LrWpanNetDevice used by Zigbee. + * @param netDevice A smart pointer to the NetDevice used by Zigbee. */ - void SetLrWpanNetDevice(Ptr lrwpanDevice); + void SetNetDevice(Ptr netDevice); protected: /** @@ -106,16 +112,10 @@ class ZigbeeStack : public Object void DoInitialize() override; private: - /** - * Configure NWK, APS layers, connect to the underlying MAC layer. - */ - void CompleteConfig(); - Ptr m_mac; //!< The underlying LrWpan MAC connected to this Zigbee Stack. Ptr m_nwk; //!< The Zigbee Network layer. Ptr m_node; //!< The node associated with this NetDevice. - Ptr - m_lrwpanNetDevice; //!< Smart pointer to the underlying LrWpanNetDevice. + Ptr m_netDevice; //!< Smart pointer to the underlying NetDevice. }; } // namespace zigbee