A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lora-channel.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 University of Padova
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 */
8
9#include "lora-channel.h"
10
11#include "lora-phy.h"
12
13#include "ns3/node.h"
14#include "ns3/pointer.h"
15#include "ns3/simulator.h"
16
17namespace ns3
18{
19namespace lorawan
20{
21
22NS_LOG_COMPONENT_DEFINE("LoraChannel");
23
25
26TypeId
28{
29 static TypeId tid =
30 TypeId("ns3::LoraChannel")
32 .SetGroupName("lorawan")
33 .AddConstructor<LoraChannel>()
34 .AddAttribute("PropagationLossModel",
35 "A pointer to the propagation loss model attached to this channel.",
39 .AddAttribute("PropagationDelayModel",
40 "A pointer to the propagation delay model attached to this channel.",
44 .AddTraceSource("PacketSent",
45 "Trace source fired whenever a packet goes out on the channel",
47 "ns3::Packet::TracedCallback");
48 return tid;
49}
50
54
59
65
66void
68{
69 NS_LOG_FUNCTION(this << phy);
70
71 // Add the new phy to the vector
72 m_phyList.push_back(phy);
73}
74
75void
77{
78 NS_LOG_FUNCTION(this << phy);
79
80 // Remove the phy from the vector
81 m_phyList.erase(find(m_phyList.begin(), m_phyList.end(), phy));
82}
83
84std::size_t
86{
87 return m_phyList.size();
88}
89
91LoraChannel::GetDevice(std::size_t i) const
92{
93 return m_phyList[i]->GetDevice();
94}
95
96void
98 Ptr<Packet> packet,
99 uint32_t frequencyHz,
100 IQPolarity iqPolarity,
101 const LoraTxParameters& txParams,
102 double txPowerDbm,
103 Time duration) const
104{
105 NS_LOG_FUNCTION(this << sender << packet << frequencyHz << iqPolarity << txParams << txPowerDbm
106 << duration);
107
108 // Get the mobility model of the sender
109 auto senderMobility = sender->GetMobility();
110 NS_ASSERT(senderMobility); // Make sure it's available
111 NS_LOG_INFO("Sender mobility: " << senderMobility->GetPosition());
112
113 // Cycle over all registered PHYs
114 NS_LOG_INFO("Starting cycle over all " << m_phyList.size() << " PHYs");
115 for (const auto& receiver : m_phyList)
116 {
117 // Do not deliver to the sender
118 if (sender != receiver)
119 {
120 // Get the receiver's mobility model
121 auto receiverMobility = receiver->GetMobility();
122 NS_ASSERT(receiverMobility); // Make sure it's available
123 NS_LOG_INFO("Receiver mobility: " << receiverMobility->GetPosition());
124
125 // Compute delay using the delay model
126 Time delay = m_delay->GetDelay(senderMobility, receiverMobility);
127
128 // Compute received power using the loss model
129 double rxPowerDbm = GetRxPower(txPowerDbm, senderMobility, receiverMobility);
130
131 NS_LOG_DEBUG("Propagation: " << "txPower=" << txPowerDbm << "dbm, "
132 << "rxPower=" << rxPowerDbm << "dbm, "
133 << "distance="
134 << senderMobility->GetDistanceFrom(receiverMobility)
135 << "m, " << "delay=" << delay);
136
137 // Get the id of the destination PHY to correctly format the context
138 uint32_t dstNode = 0;
139 if (auto dstNetDevice = receiver->GetDevice(); dstNetDevice)
140 {
141 NS_LOG_INFO("Getting node index from NetDevice, since it exists");
142 dstNode = dstNetDevice->GetNode()->GetId();
143 NS_LOG_DEBUG("dstNode=" << dstNode);
144 }
145 else
146 {
147 NS_LOG_INFO("No net device connected to the PHY, using context 0");
148 }
149
150 // Create the parameters object based on the calculations above
151 LoraChannelParameters parameters;
152 parameters.frequencyHz = frequencyHz;
153 parameters.iqPolarity = iqPolarity;
154 parameters.spreadingFactor = txParams.spreadingFactor;
155 parameters.rxPowerDbm = rxPowerDbm;
156 parameters.duration = duration;
157
158 // Schedule the receive event
159 NS_LOG_INFO("Scheduling reception of the packet");
161 delay,
163 this,
164 receiver,
165 packet,
166 parameters);
167 // Fire the trace source for sent packet
168 m_packetSent(packet);
169 }
170 }
171}
172
173double
174LoraChannel::GetRxPower(double txPowerDbm,
175 Ptr<MobilityModel> senderMobility,
176 Ptr<MobilityModel> receiverMobility) const
177{
178 return m_loss->CalcRxPower(txPowerDbm, senderMobility, receiverMobility);
179}
180
181void
183 Ptr<Packet> packet,
184 const LoraChannelParameters& parameters) const
185{
186 NS_LOG_FUNCTION(this << receiver << packet << parameters);
187 // Call the appropriate PHY instance to let it begin reception
188 receiver->StartReceive(packet,
189 parameters.frequencyHz,
190 parameters.iqPolarity,
191 parameters.spreadingFactor,
192 parameters.rxPowerDbm,
193 parameters.duration);
194}
195
196std::ostream&
197operator<<(std::ostream& os, const LoraChannel::LoraChannelParameters& params)
198{
199 os << "LoraChannelParameters("
200 << "frequencyHz=" << params.frequencyHz << " Hz, "
201 << "IQPolarity=" << params.iqPolarity << ", "
202 << "spreadingFactor=" << unsigned(params.spreadingFactor) << ", "
203 << "rxPowerDbm=" << params.rxPowerDbm << " dBm, "
204 << "duration=" << params.duration.As(Time::MS) << ")";
205 return os;
206}
207
208} // namespace lorawan
209} // namespace ns3
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:597
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
@ MS
millisecond
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
The class that delivers packets among PHY layers.
void Send(Ptr< LoraPhy > sender, Ptr< Packet > packet, uint32_t frequencyHz, IQPolarity iqPolarity, const LoraTxParameters &txParams, double txPowerDbm, Time duration) const
Send a packet in the channel.
std::size_t GetNDevices() const override
~LoraChannel() override
Destructor.
std::vector< Ptr< LoraPhy > > m_phyList
The vector containing the PHYs that are currently connected to the channel.
void Remove(Ptr< LoraPhy > phy)
Remove a physical layer from the LoraChannel.
double GetRxPower(double txPowerDbm, Ptr< MobilityModel > senderMobility, Ptr< MobilityModel > receiverMobility) const
Compute the received power when transmitting from a point to another one.
Ptr< PropagationDelayModel > m_delay
Pointer to the delay model.
LoraChannel()
Default constructor.
TracedCallback< Ptr< const Packet > > m_packetSent
Callback for when a packet is being sent on the channel.
Ptr< NetDevice > GetDevice(std::size_t i) const override
void Add(Ptr< LoraPhy > phy)
Connect a LoraPhy object to the LoraChannel.
void Receive(Ptr< LoraPhy > receiver, Ptr< Packet > packet, const LoraChannelParameters &parameters) const
Private method that is scheduled by LoraChannel's Send method to happen after the channel delay,...
Ptr< PropagationLossModel > m_loss
Pointer to the loss model.
static TypeId GetTypeId()
Register this type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
IQPolarity
I/Q Polarity of LoRa transmission symbols.
Definition lora-phy.h:33
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
std::ostream & operator<<(std::ostream &os, const EndDeviceLoraPhy::State &state)
Overloaded operator to print the value of a EndDeviceLoraPhy::State.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
A struct that holds meaningful parameters for transmission on a LoraChannel.
uint32_t frequencyHz
The frequency [Hz] of this transmission.
uint8_t spreadingFactor
The Spreading Factor of this transmission.
IQPolarity iqPolarity
The transmission's I/Q polarity (uplink or downlink).
Time duration
The duration of the transmission.
double rxPowerDbm
The average reception power.
Structure to collect all parameters that are used to compute the duration of a packet (excluding payl...
Definition lora-phy.h:73
uint8_t spreadingFactor
Symbol Spreading Factor (SF).
Definition lora-phy.h:75