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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Davide Magrin <magrinda@dei.unipd.it>
18 */
19
21
22#include "lora-tag.h"
23
24#include "ns3/log.h"
25#include "ns3/simulator.h"
26
27namespace ns3
28{
29namespace lorawan
30{
31
32NS_LOG_COMPONENT_DEFINE("SimpleGatewayLoraPhy");
33
34NS_OBJECT_ENSURE_REGISTERED(SimpleGatewayLoraPhy);
35
36/***********************************************************************
37 * Implementation of gateway methods *
38 ***********************************************************************/
39
40TypeId
42{
43 static TypeId tid = TypeId("ns3::SimpleGatewayLoraPhy")
45 .SetGroupName("lorawan")
46 .AddConstructor<SimpleGatewayLoraPhy>();
47
48 return tid;
49}
50
52{
54}
55
57{
59}
60
61void
63 LoraTxParameters txParams,
64 double frequencyMHz,
65 double txPowerDbm)
66{
67 NS_LOG_FUNCTION(this << packet << frequencyMHz << txPowerDbm);
68
69 // Get the time a packet with these parameters will take to be transmitted
70 Time duration = GetOnAirTime(packet, txParams);
71
72 NS_LOG_DEBUG("Duration of packet: " << duration << ", SF" << unsigned(txParams.sf));
73
74 // Interrupt all receive operations
75 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
76 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
77 {
79
80 if (!currentPath->IsAvailable()) // Reception path is occupied
81 {
82 // Call the callback for reception interrupted by transmission
83 // Fire the trace source
84 if (m_device)
85 {
86 m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(),
87 m_device->GetNode()->GetId());
88 }
89 else
90 {
91 m_noReceptionBecauseTransmitting(currentPath->GetEvent()->GetPacket(), 0);
92 }
93
94 // Cancel the scheduled EndReceive call
95 Simulator::Cancel(currentPath->GetEndReceive());
96
97 // Free it
98 // This also resets all parameters like packet and endReceive call
99 currentPath->Free();
100 }
101 }
102
103 // Send the packet in the channel
104 m_channel->Send(this, packet, txPowerDbm, txParams, duration, frequencyMHz);
105
107
108 m_isTransmitting = true;
109
110 // Fire the trace source
111 if (m_device)
112 {
113 m_startSending(packet, m_device->GetNode()->GetId());
114 }
115 else
116 {
117 m_startSending(packet, 0);
118 }
119}
120
121void
123 double rxPowerDbm,
124 uint8_t sf,
125 Time duration,
126 double frequencyMHz)
127{
128 NS_LOG_FUNCTION(this << packet << rxPowerDbm << duration << frequencyMHz);
129
130 // Fire the trace source
131 m_phyRxBeginTrace(packet);
132
134 {
135 // If we get to this point, there are no demodulators we can use
136 NS_LOG_INFO("Dropping packet reception of packet with sf = "
137 << unsigned(sf) << " because we are in TX mode");
138
139 m_phyRxEndTrace(packet);
140
141 // Fire the trace source
142 if (m_device)
143 {
144 m_noReceptionBecauseTransmitting(packet, m_device->GetNode()->GetId());
145 }
146 else
147 {
149 }
150
151 return;
152 }
153
154 // Add the event to the LoraInterferenceHelper
156 event = m_interference.Add(duration, rxPowerDbm, sf, packet, frequencyMHz);
157
158 // Cycle over the receive paths to check availability to receive the packet
159 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
160
161 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
162 {
164
165 // If the receive path is available and listening on the channel of
166 // interest, we have a candidate
167 if (currentPath->IsAvailable())
168 {
169 // See whether the reception power is above or below the sensitivity
170 // for that spreading factor
171 double sensitivity = SimpleGatewayLoraPhy::sensitivity[unsigned(sf) - 7];
172
173 if (rxPowerDbm < sensitivity) // Packet arrived below sensitivity
174 {
175 NS_LOG_INFO("Dropping packet reception of packet with sf = "
176 << unsigned(sf) << " because under the sensitivity of " << sensitivity
177 << " dBm");
178
179 if (m_device)
180 {
181 m_underSensitivity(packet, m_device->GetNode()->GetId());
182 }
183 else
184 {
185 m_underSensitivity(packet, 0);
186 }
187
188 // Since the packet is below sensitivity, it makes no sense to
189 // search for another ReceivePath
190 return;
191 }
192 else // We have sufficient sensitivity to start receiving
193 {
194 NS_LOG_INFO("Scheduling reception of a packet, "
195 << "occupying one demodulator");
196
197 // Block this resource
198 currentPath->LockOnEvent(event);
200
201 // Schedule the end of the reception of the packet
202 EventId endReceiveEventId =
203 Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event);
204
205 currentPath->SetEndReceive(endReceiveEventId);
206
207 // Make sure we don't go on searching for other ReceivePaths
208 return;
209 }
210 }
211 }
212 // If we get to this point, there are no demodulators we can use
213 NS_LOG_INFO("Dropping packet reception of packet with sf = "
214 << unsigned(sf) << " and frequency " << frequencyMHz
215 << "MHz because no suitable demodulator was found");
216
217 // Fire the trace source
218 if (m_device)
219 {
220 m_noMoreDemodulators(packet, m_device->GetNode()->GetId());
221 }
222 else
223 {
224 m_noMoreDemodulators(packet, 0);
225 }
226}
227
228void
230{
231 NS_LOG_FUNCTION(this << packet << *event);
232
233 // Call the trace source
234 m_phyRxEndTrace(packet);
235
236 // Call the LoraInterferenceHelper to determine whether there was
237 // destructive interference. If the packet is correctly received, this
238 // method returns a 0.
239 uint8_t packetDestroyed = 0;
240 packetDestroyed = m_interference.IsDestroyedByInterference(event);
241
242 // Check whether the packet was destroyed
243 if (packetDestroyed != uint8_t(0))
244 {
245 NS_LOG_DEBUG("packetDestroyed by " << unsigned(packetDestroyed));
246
247 // Update the packet's LoraTag
248 LoraTag tag;
249 packet->RemovePacketTag(tag);
250 tag.SetDestroyedBy(packetDestroyed);
251 packet->AddPacketTag(tag);
252
253 // Fire the trace source
254 if (m_device)
255 {
256 m_interferedPacket(packet, m_device->GetNode()->GetId());
257 }
258 else
259 {
260 m_interferedPacket(packet, 0);
261 }
262 }
263 else // Reception was correct
264 {
265 NS_LOG_INFO("Packet with SF " << unsigned(event->GetSpreadingFactor())
266 << " received correctly");
267
268 // Fire the trace source
269 if (m_device)
270 {
271 m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId());
272 }
273 else
274 {
276 }
277
278 // Forward the packet to the upper layer
279 if (!m_rxOkCallback.IsNull())
280 {
281 // Make a copy of the packet
282 // Ptr<Packet> packetCopy = packet->Copy ();
283
284 // Set the receive power and frequency of this packet in the LoraTag: this
285 // information can be useful for upper layers trying to control link
286 // quality.
287 LoraTag tag;
288 packet->RemovePacketTag(tag);
289 tag.SetReceivePower(event->GetRxPowerdBm());
290 tag.SetFrequency(event->GetFrequency());
291 packet->AddPacketTag(tag);
292
293 m_rxOkCallback(packet);
294 }
295 }
296
297 // Search for the demodulator that was locked on this event to free it.
298
299 std::list<Ptr<SimpleGatewayLoraPhy::ReceptionPath>>::iterator it;
300
301 for (it = m_receptionPaths.begin(); it != m_receptionPaths.end(); ++it)
302 {
304
305 if (currentPath->GetEvent() == event)
306 {
307 currentPath->Free();
309 return;
310 }
311 }
312}
313
314} // namespace lorawan
315} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
An identifier for simulation events.
Definition: event-id.h:56
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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:307
LoraInterferenceHelper m_interference
The LoraInterferenceHelper associated to this PHY.
Definition: lora-phy.h:289
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:167
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:324
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:312
TracedCallback< Ptr< const Packet >, uint32_t > m_startSending
The trace source fired when a packet is sent.
Definition: lora-phy.h:296
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:318
Ptr< NetDevice > m_device
The net device this PHY is attached to.
Definition: lora-phy.h:285
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: lora-phy.h:302
Ptr< LoraChannel > m_channel
The channel this PHY transmits on.
Definition: lora-phy.h:287
RxOkCallback m_rxOkCallback
The callback to perform upon correct reception of a packet.
Definition: lora-phy.h:331
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition: lora-tag.h:37
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition: lora-tag.cc:130
void SetReceivePower(double receivePower)
Set the power this packet was received with.
Definition: lora-tag.cc:124
void SetDestroyedBy(uint8_t sf)
Set which Spreading Factor this packet was destroyed by.
Definition: lora-tag.cc:112
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:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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:49
uint8_t sf
Spreading Factor.
Definition: lora-phy.h:50