A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
simple-gateway-lora-phy.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
10
11#include "lora-tag.h"
12
13#include "ns3/log.h"
14#include "ns3/simulator.h"
15
16namespace ns3
17{
18namespace lorawan
19{
20
21NS_LOG_COMPONENT_DEFINE("SimpleGatewayLoraPhy");
22
23NS_OBJECT_ENSURE_REGISTERED(SimpleGatewayLoraPhy);
24
25/***********************************************************************
26 * Implementation of gateway methods *
27 ***********************************************************************/
28
29TypeId
31{
32 static TypeId tid = TypeId("ns3::SimpleGatewayLoraPhy")
34 .SetGroupName("lorawan")
35 .AddConstructor<SimpleGatewayLoraPhy>();
36
37 return tid;
38}
39
44
49
50void
52 LoraTxParameters txParams,
53 double frequencyMHz,
54 double txPowerDbm)
55{
56 NS_LOG_FUNCTION(this << packet << frequencyMHz << txPowerDbm);
57
58 // Get the time a packet with these parameters will take to be transmitted
59 Time duration = GetOnAirTime(packet, txParams);
60
61 NS_LOG_DEBUG("Duration of packet: " << duration << ", SF" << unsigned(txParams.sf));
62
63 // Interrupt all receive operations
64 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
65 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
66 {
68
69 if (!currentPath->IsAvailable()) // Reception path is occupied
70 {
71 // Call the callback for reception interrupted by transmission
72 // Fire the trace source
73 if (m_device)
74 {
75 m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(),
76 m_device->GetNode()->GetId());
77 }
78 else
79 {
80 m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(), 0);
81 }
82
83 // Cancel the scheduled EndReceive call
84 Simulator::Cancel(currentPath->GetEndReceive());
85
86 // Free it
87 // This also resets all parameters like packet and endReceive call
88 currentPath->Free();
89 }
90 }
91
92 // Send the packet in the channel
93 m_channel->Send(this, packet, txPowerDbm, txParams, duration, frequencyMHz);
94
96
97 m_isTransmitting = true;
98
99 // Fire the trace source
100 if (m_device)
101 {
102 m_startSending(packet, m_device->GetNode()->GetId());
103 }
104 else
105 {
106 m_startSending(packet, 0);
107 }
108}
109
110void
112 double rxPowerDbm,
113 uint8_t sf,
114 Time duration,
115 double frequencyMHz)
116{
117 NS_LOG_FUNCTION(this << packet << rxPowerDbm << duration << frequencyMHz);
118
119 // Fire the trace source
120 m_phyRxBeginTrace(packet);
121
123 {
124 // If we get to this point, there are no demodulators we can use
125 NS_LOG_INFO("Dropping packet reception of packet with sf = "
126 << unsigned(sf) << " because we are in TX mode");
127
128 m_phyRxEndTrace(packet);
129
130 // Fire the trace source
131 if (m_device)
132 {
133 m_noReceptionBecauseTransmitting(packet, m_device->GetNode()->GetId());
134 }
135 else
136 {
138 }
139
140 return;
141 }
142
143 // Add the event to the LoraInterferenceHelper
145 event = m_interference.Add(duration, rxPowerDbm, sf, packet, frequencyMHz);
146
147 // Cycle over the receive paths to check availability to receive the packet
148 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
149
150 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
151 {
153
154 // If the receive path is available and listening on the channel of
155 // interest, we have a candidate
156 if (currentPath->IsAvailable())
157 {
158 // See whether the reception power is above or below the sensitivity
159 // for that spreading factor
160 double sensitivity = SimpleGatewayLoraPhy::sensitivity[unsigned(sf) - 7];
161
162 if (rxPowerDbm < sensitivity) // Packet arrived below sensitivity
163 {
164 NS_LOG_INFO("Dropping packet reception of packet with sf = "
165 << unsigned(sf) << " because under the sensitivity of " << sensitivity
166 << " dBm");
167
168 if (m_device)
169 {
170 m_underSensitivity(packet, m_device->GetNode()->GetId());
171 }
172 else
173 {
174 m_underSensitivity(packet, 0);
175 }
176
177 // Since the packet is below sensitivity, it makes no sense to
178 // search for another ReceivePath
179 return;
180 }
181 else // We have sufficient sensitivity to start receiving
182 {
183 NS_LOG_INFO("Scheduling reception of a packet, occupying one demodulator");
184
185 // Block this resource
186 currentPath->LockOnEvent(event);
188
189 // Schedule the end of the reception of the packet
190 EventId endReceiveEventId =
191 Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event);
192
193 currentPath->SetEndReceive(endReceiveEventId);
194
195 // Make sure we don't go on searching for other ReceivePaths
196 return;
197 }
198 }
199 }
200 // If we get to this point, there are no demodulators we can use
201 NS_LOG_INFO("Dropping packet reception of packet with sf = "
202 << unsigned(sf) << " and frequency " << frequencyMHz
203 << "MHz because no suitable demodulator was found");
204
205 // Fire the trace source
206 if (m_device)
207 {
208 m_noMoreDemodulators(packet, m_device->GetNode()->GetId());
209 }
210 else
211 {
212 m_noMoreDemodulators(packet, 0);
213 }
214}
215
216void
218{
219 NS_LOG_FUNCTION(this << packet << *event);
220
221 // Call the trace source
222 m_phyRxEndTrace(packet);
223
224 // Call the LoraInterferenceHelper to determine whether there was
225 // destructive interference. If the packet is correctly received, this
226 // method returns a 0.
227 uint8_t packetDestroyed = 0;
228 packetDestroyed = m_interference.IsDestroyedByInterference(event);
229
230 // Check whether the packet was destroyed
231 if (packetDestroyed != uint8_t(0))
232 {
233 NS_LOG_DEBUG("packetDestroyed by " << unsigned(packetDestroyed));
234
235 // Update the packet's LoraTag
236 LoraTag tag;
237 packet->RemovePacketTag(tag);
238 tag.SetDestroyedBy(packetDestroyed);
239 packet->AddPacketTag(tag);
240
241 // Fire the trace source
242 if (m_device)
243 {
244 m_interferedPacket(packet, m_device->GetNode()->GetId());
245 }
246 else
247 {
248 m_interferedPacket(packet, 0);
249 }
250 }
251 else // Reception was correct
252 {
253 NS_LOG_INFO("Packet with SF " << unsigned(event->GetSpreadingFactor())
254 << " received correctly");
255
256 // Fire the trace source
257 if (m_device)
258 {
259 m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId());
260 }
261 else
262 {
264 }
265
266 // Forward the packet to the upper layer
267 if (!m_rxOkCallback.IsNull())
268 {
269 // Make a copy of the packet
270 // Ptr<Packet> packetCopy = packet->Copy ();
271
272 // Set the receive power and frequency of this packet in the LoraTag: this
273 // information can be useful for upper layers trying to control link
274 // quality.
275 LoraTag tag;
276 packet->RemovePacketTag(tag);
277 tag.SetReceivePower(event->GetRxPowerdBm());
278 tag.SetFrequency(event->GetFrequency());
279 packet->AddPacketTag(tag);
280
281 m_rxOkCallback(packet);
282 }
283 }
284
285 // Search for the demodulator that was locked on this event to free it.
286
287 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
288
289 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
290 {
292
293 if (currentPath->GetEvent() == event)
294 {
295 currentPath->Free();
297 return;
298 }
299 }
300}
301
302} // namespace lorawan
303} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition callback.h:555
An identifier for simulation events.
Definition event-id.h:45
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.
Definition simulator.h:560
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition simulator.cc:274
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Class modeling a Lora SX1301 chip.
bool m_isTransmitting
Flag indicating whether a transmission is going on.
TracedValue< int > m_occupiedReceptionPaths
The number of occupied reception paths.
static const double sensitivity[6]
A vector containing the sensitivities required to correctly decode different spreading factors.
TracedCallback< Ptr< const Packet >, uint32_t > m_noReceptionBecauseTransmitting
Trace source fired when a packet cannot be received because the gateway is in transmission state.
void TxFinished(Ptr< const Packet > packet) override
Signals the end of a transmission by the GatewayLoraPhy.
std::list< Ptr< ReceptionPath > > m_receptionPaths
A list containing the various parallel receivers that are managed by this gateway.
TracedCallback< Ptr< const Packet >, uint32_t > m_noMoreDemodulators
Trace source fired when a packet cannot be received because all available ReceivePath instances are b...
Ptr< LoraInterferenceHelper::Event > Add(Time duration, double rxPower, uint8_t spreadingFactor, Ptr< Packet > packet, double frequencyMHz)
Add an event to the InterferenceHelper.
uint8_t IsDestroyedByInterference(Ptr< LoraInterferenceHelper::Event > event)
Determine whether the event was destroyed by interference or not.
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet reception ends.
Definition lora-phy.h:296
LoraInterferenceHelper m_interference
The LoraInterferenceHelper associated to this PHY.
Definition lora-phy.h:278
static Time GetOnAirTime(Ptr< Packet > packet, LoraTxParameters txParams)
Compute the time that a packet with certain characteristics will take to be transmitted.
Definition lora-phy.cc:156
TracedCallback< Ptr< const Packet >, uint32_t > m_interferedPacket
The trace source fired when a packet cannot be correctly received because of interference.
Definition lora-phy.h:313
virtual void EndReceive(Ptr< Packet > packet, Ptr< LoraInterferenceHelper::Event > event)=0
Finish reception of a packet.
TracedCallback< Ptr< const Packet >, uint32_t > m_successfullyReceivedPacket
The trace source fired when a packet was correctly received.
Definition lora-phy.h:301
TracedCallback< Ptr< const Packet >, uint32_t > m_startSending
The trace source fired when a packet is sent.
Definition lora-phy.h:285
TracedCallback< Ptr< const Packet >, uint32_t > m_underSensitivity
The trace source fired when a packet cannot be received because its power is below the sensitivity th...
Definition lora-phy.h:307
Ptr< NetDevice > m_device
The net device this PHY is attached to.
Definition lora-phy.h:274
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition lora-phy.h:291
Ptr< LoraChannel > m_channel
The channel this PHY transmits on.
Definition lora-phy.h:276
RxOkCallback m_rxOkCallback
The callback to perform upon correct reception of a packet.
Definition lora-phy.h:320
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:26
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition lora-tag.cc:119
void SetReceivePower(double receivePower)
Set the power this packet was received with.
Definition lora-tag.cc:113
void SetDestroyedBy(uint8_t sf)
Set which Spreading Factor this packet was destroyed by.
Definition lora-tag.cc:101
Class modeling a Lora SX1301 chip.
void Send(Ptr< Packet > packet, LoraTxParameters txParams, double frequencyMHz, double txPowerDbm) override
Instruct the PHY to send a packet according to some parameters.
static TypeId GetTypeId()
Register this type.
void StartReceive(Ptr< Packet > packet, double rxPowerDbm, uint8_t sf, Time duration, double frequencyMHz) override
Start receiving a packet.
void EndReceive(Ptr< Packet > packet, Ptr< LoraInterferenceHelper::Event > event) override
Finish reception of a packet.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Structure to collect all parameters that are used to compute the duration of a packet (excluding payl...
Definition lora-phy.h:38
uint8_t sf
Spreading Factor.
Definition lora-phy.h:39