Skip to content

Commit

Permalink
zigbee: Aggregated LrWpanMacBase support
Browse files Browse the repository at this point in the history
  • Loading branch information
Alberto Gallegos Ramonet committed Dec 19, 2024
1 parent a0120b7 commit 952bc77
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 113 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
31 changes: 17 additions & 14 deletions src/lr-wpan/doc/lr-wpan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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:

Expand All @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/lr-wpan/model/lr-wpan-mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -272,6 +275,8 @@ LrWpanMac::DoInitialize()
void
LrWpanMac::DoDispose()
{
NS_LOG_FUNCTION(this);

if (m_csmaCa)
{
m_csmaCa->Dispose();
Expand All @@ -291,6 +296,7 @@ LrWpanMac::DoDispose()
}
m_indTxQueue.clear();

m_uniformVar = nullptr;
m_phy = nullptr;
m_mcpsDataConfirmCallback = MakeNullCallback<void, McpsDataConfirmParams>();
m_mcpsDataIndicationCallback = MakeNullCallback<void, McpsDataIndicationParams, Ptr<Packet>>();
Expand Down
37 changes: 15 additions & 22 deletions src/lr-wpan/model/lr-wpan-net-device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ LrWpanNetDevice::LrWpanNetDevice()
: m_configComplete(false)
{
NS_LOG_FUNCTION(this);
m_mac = CreateObject<LrWpanMac>();

m_phy = CreateObject<LrWpanPhy>();
m_csmaca = CreateObject<LrWpanCsmaCa>();
CompleteConfig();
m_mac = CreateObject<LrWpanMac>();
}

LrWpanNetDevice::~LrWpanNetDevice()
Expand All @@ -91,7 +91,6 @@ void
LrWpanNetDevice::DoDispose()
{
NS_LOG_FUNCTION(this);
m_mac->Dispose();
m_phy->Dispose();
m_csmaca->Dispose();
m_phy = nullptr;
Expand All @@ -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));
Expand Down Expand Up @@ -146,75 +148,68 @@ LrWpanNetDevice::CompleteConfig()
void
LrWpanNetDevice::SetMac(Ptr<LrWpanMac> 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<LrWpanPhy> 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<LrWpanCsmaCa> 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<SpectrumChannel> 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<LrWpanMac>
LrWpanNetDevice::GetMac() const
{
// NS_LOG_FUNCTION (this);
return m_mac;
}

Ptr<LrWpanPhy>
LrWpanNetDevice::GetPhy() const
{
NS_LOG_FUNCTION(this);
return m_phy;
}

Ptr<LrWpanCsmaCa>
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<Channel>
LrWpanNetDevice::GetChannel() const
{
NS_LOG_FUNCTION(this);
return m_phy->GetChannel();
}

Expand Down Expand Up @@ -449,14 +444,12 @@ LrWpanNetDevice::SendFrom(Ptr<Packet> packet,
Ptr<Node>
LrWpanNetDevice::GetNode() const
{
NS_LOG_FUNCTION(this);
return m_node;
}

void
LrWpanNetDevice::SetNode(Ptr<Node> node)
{
NS_LOG_FUNCTION(this);
m_node = node;
CompleteConfig();
}
Expand Down
14 changes: 14 additions & 0 deletions src/lr-wpan/test/lr-wpan-ifs-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
5 changes: 5 additions & 0 deletions src/lr-wpan/test/lr-wpan-slotted-csmaca-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
16 changes: 8 additions & 8 deletions src/sixlowpan/test/sixlowpan-example-ping-lr-wpan.reflog
Original file line number Diff line number Diff line change
@@ -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
2001:2::ff:fe00:1 dev 2 lladdr 00-06-02:00:00:00:00:01 REACHABLE
8 changes: 6 additions & 2 deletions src/zigbee/doc/zigbee.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down
11 changes: 4 additions & 7 deletions src/zigbee/helper/zigbee-helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -45,16 +44,14 @@ ZigbeeHelper::Install(const NetDeviceContainer c)
{
Ptr<NetDevice> device = c.Get(i);

NS_ASSERT_MSG(device != nullptr, "No LrWpanNetDevice found in the node " << i);
Ptr<lrwpan::LrWpanNetDevice> lrwpanNetdevice = DynamicCast<lrwpan::LrWpanNetDevice>(device);
NS_ASSERT_MSG(device, "NetDevice not found in the node " << i);

Ptr<Node> node = lrwpanNetdevice->GetNode();
NS_LOG_LOGIC("**** Install Zigbee on node " << node->GetId());
NS_LOG_LOGIC("Installing Zigbee on node " << device->GetNode()->GetId());

Ptr<zigbee::ZigbeeStack> zigbeeStack = m_stackFactory.Create<zigbee::ZigbeeStack>();
zigbeeStackContainer.Add(zigbeeStack);
node->AggregateObject(zigbeeStack);
zigbeeStack->SetLrWpanNetDevice(lrwpanNetdevice);
device->GetNode()->AggregateObject(zigbeeStack);
zigbeeStack->SetNetDevice(device);
}
return zigbeeStackContainer;
}
Expand Down
Loading

0 comments on commit 952bc77

Please sign in to comment.