10#include "ns3/constant-position-mobility-model.h"
12#include "ns3/lora-helper.h"
13#include "ns3/mobility-helper.h"
14#include "ns3/one-shot-sender-helper.h"
15#include "ns3/simple-end-device-lora-phy.h"
16#include "ns3/simple-gateway-lora-phy.h"
22using namespace lorawan;
39 void DoRun()
override;
44 :
TestCase(
"Verify that LoraInterferenceHelper works as expected")
62 double frequency = 868.1;
63 double differentFrequency = 868.3;
69 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
70 event1 = interferenceHelper.
Add(
Seconds(1), 14, 12,
nullptr, frequency);
73 "Overlap computation didn't give the expected result");
76 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
77 event1 = interferenceHelper.
Add(
Seconds(1.5), 14, 12,
nullptr, frequency);
80 "Overlap computation didn't give the expected result");
83 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
84 event1 = interferenceHelper.
Add(
Seconds(3), 14, 12,
nullptr, frequency);
87 "Overlap computation didn't give the expected result");
90 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
91 event1 = interferenceHelper.
Add(
Seconds(2), 14, 12,
nullptr, frequency);
99 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
100 interferenceHelper.
Add(
Seconds(2), 14, 12,
nullptr, frequency);
103 "Packet did not survive interference as expected");
107 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
108 interferenceHelper.
Add(
Seconds(2), 14 - 7, 7,
nullptr, frequency);
111 "Packet did not survive interference as expected");
115 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
116 interferenceHelper.
Add(
Seconds(2), 14 - 6, 7,
nullptr, frequency);
119 "Packet was not destroyed by interference as expected");
123 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
124 interferenceHelper.
Add(
Seconds(1), 14 - 6, 7,
nullptr, frequency);
127 "Packet did not survive interference as expected");
133 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
134 interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, differentFrequency);
137 "Packet did not survive interference as expected");
143 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
144 interferenceHelper.
Add(
Seconds(2), 14 + 16, 8,
nullptr, frequency);
147 "Packet did not survive interference as expected");
152 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
153 interferenceHelper.
Add(
Seconds(2), 14 + 17, 8,
nullptr, frequency);
156 "Packet was not destroyed by interference as expected");
160 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
161 interferenceHelper.
Add(
Seconds(2), 14 + 17, 10,
nullptr, frequency);
164 "Packet was destroyed by interference while it should have survived");
169 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
170 interferenceHelper.
Add(
Seconds(2), 14 + 16, 8,
nullptr, frequency);
171 interferenceHelper.
Add(
Seconds(2), 14 + 16, 8,
nullptr, frequency);
172 interferenceHelper.
Add(
Seconds(2), 14 + 16, 8,
nullptr, frequency);
175 "Packet was not destroyed by interference as expected");
180 event = interferenceHelper.
Add(
Seconds(2), 14, 7,
nullptr, frequency);
181 interferenceHelper.
Add(
Seconds(2), 14 + 16, 8,
nullptr, frequency);
182 interferenceHelper.
Add(
Seconds(2), 14 + 16, 9,
nullptr, frequency);
183 interferenceHelper.
Add(
Seconds(2), 14 + 16, 10,
nullptr, frequency);
186 "Packet did not survive interference as expected");
203 void DoRun()
override;
208 :
TestCase(
"Verify that LoraDeviceAddress works as expected")
238 "> function for addresses doesn't work correctly");
244 address.SetNwkAddr(0xFFFFFFF);
245 address.SetNwkID(0b1111111);
248 "Addresses set to be equal don't match");
257 "Serialization + Deserialization doesn't yield an equal address");
264 for (
int i = 0; i < 200; i++)
271 "LoraDeviceAddressGenerator doesn't increment as expected");
287 void DoRun()
override;
292 :
TestCase(
"Verify that LorawanMacHeader and LoraFrameHeader work as expected")
324 "MType changes in the serialization/deserialization process");
327 "MType changes in the serialization/deserialization process");
350 uint8_t margin = command->GetMargin();
351 uint8_t gwCnt = command->GetGwCnt();
355 "ACK bit changes in the serialization/deserialization process");
358 "ADR bit changes in the serialization/deserialization process");
361 "FCnt changes in the serialization/deserialization process");
364 "Address changes in the serialization/deserialization process");
367 "Margin changes in the serialization/deserialization process");
374 pkt->AddHeader(frameHdr);
375 pkt->AddHeader(macHdr);
383 pkt->RemoveHeader(macHdr1);
390 pkt->RemoveHeader(frameHdr1);
395 "Wrong size of packet + headers - macHeader - frameHeader");
400 "Removed header contents don't match");
403 "Removed header contents don't match");
408 "Removed header contents don't match");
411 "Removed header contents don't match");
414 "Removed header contents don't match");
417 "Removed header contents don't match");
420 "Removed header's MAC command contents don't match");
423 "Removed header's MAC command contents don't match");
440 void DoRun()
override;
484 :
TestCase(
"Verify that ReceivePaths work as expected")
872 void DoRun()
override;
877 :
TestCase(
"Verify that LogicalLoraChannel and LogicalLoraChannelHelper work as expected")
914 SubBand subBand(868, 868.7, 0.01, 14);
920 "BelongsToSubBand does not behave as expected");
923 "BelongsToSubBand does not behave as expected");
926 "BelongsToSubBand does not behave as expected");
934 SubBand subBand1(869, 869.4, 0.1, 27);
947 channelHelper->AddSubBand(&subBand);
948 channelHelper->AddSubBand(&subBand1);
949 channelHelper->AddChannel(channel1);
950 channelHelper->AddChannel(channel2);
951 channelHelper->AddChannel(channel3);
952 channelHelper->AddChannel(channel4);
953 channelHelper->AddChannel(channel5);
959 channelHelper->AddEvent(
Seconds(2), channel1);
965 "Waiting time doesn't behave as expected");
970 "Waiting time doesn't behave as expected");
973 "Waiting time doesn't behave as expected");
978 "Waiting time affects other subbands");
981 "Waiting time affects other subbands");
997 void DoRun()
override;
1003 "Verify that LoraPhy's function to compute the time on air of a packet works as expected")
1165 void DoRun()
override;
1182 :
TestCase(
"Verify that PhyConnectivity works as expected")
1236 return packet1->GetUid() == packet2->GetUid();
1249 loss->SetPathLossExponent(3.76);
1250 loss->SetReference(1, 7.7);
1262 edPhy1->SetFrequency(868.1);
1263 edPhy2->SetFrequency(868.1);
1264 edPhy3->SetFrequency(868.1);
1270 mob1->SetPosition(Vector(0.0, 0.0, 0.0));
1271 mob2->SetPosition(Vector(10.0, 0.0, 0.0));
1272 mob3->SetPosition(Vector(20.0, 0.0, 0.0));
1274 edPhy1->SetMobility(mob1);
1275 edPhy2->SetMobility(mob2);
1276 edPhy3->SetMobility(mob3);
1278 edPhy1->SwitchToStandby();
1279 edPhy2->SwitchToStandby();
1280 edPhy3->SwitchToStandby();
1291 edPhy1->SetSpreadingFactor(12);
1292 edPhy2->SetSpreadingFactor(12);
1293 edPhy3->SetSpreadingFactor(12);
1296 edPhy1->SetFrequency(868.1);
1297 edPhy2->SetFrequency(868.1);
1298 edPhy3->SetFrequency(868.1);
1300 edPhy1->TraceConnectWithoutContext(
"ReceivedPacket",
1302 edPhy2->TraceConnectWithoutContext(
"ReceivedPacket",
1304 edPhy3->TraceConnectWithoutContext(
"ReceivedPacket",
1307 edPhy1->TraceConnectWithoutContext(
"LostPacketBecauseUnderSensitivity",
1309 edPhy2->TraceConnectWithoutContext(
"LostPacketBecauseUnderSensitivity",
1311 edPhy3->TraceConnectWithoutContext(
"LostPacketBecauseUnderSensitivity",
1314 edPhy1->TraceConnectWithoutContext(
"LostPacketBecauseInterference",
1316 edPhy2->TraceConnectWithoutContext(
"LostPacketBecauseInterference",
1318 edPhy3->TraceConnectWithoutContext(
"LostPacketBecauseInterference",
1321 edPhy1->TraceConnectWithoutContext(
"LostPacketBecauseWrongFrequency",
1323 edPhy2->TraceConnectWithoutContext(
"LostPacketBecauseWrongFrequency",
1325 edPhy3->TraceConnectWithoutContext(
"LostPacketBecauseWrongFrequency",
1328 edPhy1->TraceConnectWithoutContext(
"LostPacketBecauseWrongSpreadingFactor",
1330 edPhy2->TraceConnectWithoutContext(
"LostPacketBecauseWrongSpreadingFactor",
1332 edPhy3->TraceConnectWithoutContext(
"LostPacketBecauseWrongSpreadingFactor",
1351 uint8_t buffer[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1375 "Channel skipped some PHYs when delivering a packet");
1398 "Packet was received by a PHY in SLEEP mode");
1405 edPhy2->SetSpreadingFactor(7);
1407 ->SetPosition(Vector(2990, 0, 0));
1424 "Packet that should have been lost because of low receive power was received");
1430 edPhy2->SetSpreadingFactor(8);
1432 ->SetPosition(Vector(2990, 0, 0));
1448 "Packets that should have arrived above sensitivity were under it");
1476 "Packets that should be destroyed by interference weren't");
1496 "Packets were received even though PHY was on a different frequency");
1518 "Packets were received even though PHY was listening for a different spreading factor.");
1540 "Packet changed contents when going through the channel");
1562 SimpleEndDeviceLoraPhy::STANDBY,
1563 "State didn't switch to STANDBY as expected");
1565 SimpleEndDeviceLoraPhy::STANDBY,
1566 "State didn't switch to STANDBY as expected");
1583 void DoRun()
override;
1588 :
TestCase(
"Verify that the MAC layer of end devices behaves as expected")
It tests LoraDeviceAddress comparison operators overrides and generation of new addresses with LoraDe...
AddressTest()
Default constructor.
void DoRun() override
Implementation to actually run this TestCase.
~AddressTest() override
Destructor.
It tests interference computations in a number of possible scenarios using the LoraInterferenceHelper...
~InterferenceTest() override
Destructor.
void DoRun() override
Implementation to actually run this TestCase.
InterferenceTest()
Default constructor.
It tests functionality of the LogicalLoraChannel, SubBand and LogicalLoraChannelHelper classes.
LogicalLoraChannelTest()
Default constructor.
~LogicalLoraChannelTest() override
Destructor.
void DoRun() override
Implementation to actually run this TestCase.
It tests the functionalities of the MAC layer of LoRaWAN devices.
~LorawanMacTest() override
Destructor.
LorawanMacTest()
Default constructor.
void DoRun() override
Implementation to actually run this TestCase.
The TestSuite class names the TestSuite, identifies what type of TestSuite, and enables the TestCases...
LorawanTestSuite()
Default constructor.
It tests sending packets over a LoRa physical channel between multiple devices and the resulting poss...
int m_interferenceCalls
Counter for LostPacketBecauseInterference calls.
void Reset()
Reset counters and end devices' PHYs for new sub test case.
Ptr< SimpleEndDeviceLoraPhy > edPhy2
The second end device's PHY layer used in tests.
void WrongFrequency(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseWrongFrequency.
void DoRun() override
Implementation to actually run this TestCase.
void UnderSensitivity(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseUnderSensitivity.
bool IsSamePacket(Ptr< Packet > packet1, Ptr< Packet > packet2)
Compare two packets to check if they are equal.
Ptr< SimpleEndDeviceLoraPhy > edPhy3
The third end device's PHY layer used in tests.
Ptr< SimpleEndDeviceLoraPhy > edPhy1
The first end device's PHY layer used in tests.
int m_wrongSfCalls
Counter for LostPacketBecauseWrongSpreadingFactor calls.
int m_wrongFrequencyCalls
Counter for LostPacketBecauseWrongFrequency calls.
~PhyConnectivityTest() override
Destructor.
int m_underSensitivityCalls
Counter for LostPacketBecauseUnderSensitivity calls.
int m_receivedPacketCalls
Counter for ReceivedPacket calls.
void WrongSf(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseWrongSpreadingFactor.
Ptr< LoraChannel > channel
The LoRa channel used for tests.
PhyConnectivityTest()
Default constructor.
void Interference(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseInterference.
Ptr< Packet > m_latestReceivedPacket
Pointer to track the last received packet.
void ReceivedPacket(Ptr< const Packet > packet, uint32_t node)
Callback for tracing ReceivedPacket.
It tests a number of cases related to SimpleGatewayLoraPhy's parallel reception paths.
~ReceivePathTest() override
Destructor.
ReceivePathTest()
Default constructor.
int m_receivedPacketCalls
Counter for ReceivedPacket calls.
void OccupiedReceptionPaths(int oldValue, int newValue)
Callback for tracing OccupiedReceptionPaths.
Ptr< SimpleGatewayLoraPhy > gatewayPhy
PHY layer of a gateway to be tested.
void ReceivedPacket(Ptr< const Packet > packet, uint32_t node)
Callback for tracing ReceivedPacket.
void Interference(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseInterference.
void NoMoreDemodulators(Ptr< const Packet > packet, uint32_t node)
Callback for tracing LostPacketBecauseNoMoreReceivers.
void DoRun() override
Implementation to actually run this TestCase.
int m_noMoreDemodulatorsCalls
Counter for LostPacketBecauseNoMoreReceivers calls.
void Reset()
Reset counters and gateway PHY for new sub test case.
int m_interferenceCalls
Counter for LostPacketBecauseInterference calls.
int m_maxOccupiedReceptionPaths
Max number of concurrent OccupiedReceptionPaths.
It tests the correctness of the LoraPhy::GetOnAirTime calculator against a number of pre-sourced time...
void DoRun() override
Implementation to actually run this TestCase.
~TimeOnAirTest() override
Destructor.
TimeOnAirTest()
Default constructor.
iterator in a Buffer instance
automatically resized byte buffer
void AddAtStart(uint32_t start)
Buffer::Iterator Begin() const
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
This class generates sequential LoraDeviceAddress instances.
LoraDeviceAddress NextAddress()
Allocate the next LoraDeviceAddress.
LoraDeviceAddress GetNextAddress()
Get the LoraDeviceAddress that will be allocated upon a call to NextAddress.
This class represents the device address of a LoraWAN end device.
static LoraDeviceAddress Deserialize(const uint8_t buf[4])
Convert the input buffer into a new address.
void Serialize(uint8_t buf[4]) const
Convert this address to a buffer.
Helper for LoraPhy that manages interference calculations.
Ptr< LoraInterferenceHelper::Event > Add(Time duration, double rxPower, uint8_t spreadingFactor, Ptr< Packet > packet, double frequencyMHz)
Add an event to the InterferenceHelper.
Time GetOverlapTime(Ptr< LoraInterferenceHelper::Event > event1, Ptr< LoraInterferenceHelper::Event > event2)
Compute the time duration in which two given events are overlapping.
void ClearAllEvents()
Delete all events in the LoraInterferenceHelper.
uint8_t IsDestroyedByInterference(Ptr< LoraInterferenceHelper::Event > event)
Determine whether the event was destroyed by interference or not.
static Time GetOnAirTime(Ptr< Packet > packet, LoraTxParameters txParams)
Compute the time that a packet with certain characteristics will take to be transmitted.
void Send(Ptr< Packet > packet, LoraTxParameters txParams, double frequencyMHz, double txPowerDbm) override
Instruct the PHY to send a packet according to some parameters.
Class representing a SubBand, i.e., a frequency band subject to some regulations on duty cycle and tr...
bool BelongsToSubBand(double frequency) const
Return whether or not a frequency belongs to this SubBand.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Time Seconds(double value)
Construct a Time in the indicated unit.
Time Hours(double value)
Construct a Time in the indicated unit.
static LorawanTestSuite lorawanTestSuite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
@ LOG_LEVEL_DEBUG
LOG_DEBUG and above.
Structure to collect all parameters that are used to compute the duration of a packet (excluding payl...
uint8_t codingRate
Code rate (obtained as 4/(codingRate+4))
uint32_t nPreamble
Number of preamble symbols.
bool headerDisabled
Whether to use implicit header mode.
double bandwidthHz
Bandwidth in Hz.
bool lowDataRateOptimizationEnabled
Whether low data rate optimization is enabled.
bool crcEnabled
Whether Cyclic Redundancy Check (CRC) is enabled.
uint8_t sf
Spreading Factor.