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-channel.h"
12#include "lora-tag.h"
13
14#include "ns3/node.h"
15#include "ns3/simulator.h"
16
17namespace ns3
18{
19namespace lorawan
20{
21
22NS_LOG_COMPONENT_DEFINE("SimpleGatewayLoraPhy");
23
25
26/***********************************************************************
27 * Implementation of gateway methods *
28 ***********************************************************************/
29
30TypeId
32{
33 static TypeId tid = TypeId("ns3::SimpleGatewayLoraPhy")
35 .SetGroupName("lorawan")
36 .AddConstructor<SimpleGatewayLoraPhy>();
37
38 return tid;
39}
40
45
50
51void
53 uint32_t frequencyHz,
54 IQPolarity iqPolarity,
55 const LoraTxParameters& txParams,
56 double txPowerDbm)
57{
58 NS_LOG_FUNCTION(this << packet << frequencyHz << iqPolarity << txParams << txPowerDbm);
59
60 // Interrupt all receive operations
61 for (auto& rxPath : m_receptionPaths)
62 {
63 if (!rxPath->IsAvailable()) // Reception path is occupied
64 {
65 // Fire the trace source
66 m_noReceptionBecauseTransmitting(rxPath->GetEvent()->GetPacket(),
67 (m_device) ? m_device->GetNode()->GetId() : 0);
68 // Free the reception path (reset state and cancels reception end)
69 rxPath->Free();
70 }
71 }
72
73 // Switch to TX state
74 m_isTransmitting = true;
75 // Fire the trace source
76 m_startSending(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
77
78 // Compute the duration of the modulated transmission
79 Time duration = GetTimeOnAir(packet->GetSize(), txParams);
80 // Propagate the transmission over the channel (schedule StartReceive for other nodes)
81 m_channel->Send(this, packet, frequencyHz, iqPolarity, txParams, txPowerDbm, duration);
82
83 // Schedule a call to self to signal the transmission modulation end
85}
86
87void
89 uint32_t frequencyHz,
90 IQPolarity iqPolarity,
91 uint8_t spreadingFactor,
92 double rxPowerDbm,
93 Time duration)
94{
95 NS_LOG_FUNCTION(this << packet << frequencyHz << iqPolarity << unsigned(spreadingFactor)
96 << rxPowerDbm << duration);
97
98 // Add the event to the LoraInterferenceHelper
99 auto event = m_interference.Add(duration, rxPowerDbm, spreadingFactor, packet, frequencyHz);
100
101 // Check whether the gateway is currently transmitting downlink
103 {
104 NS_LOG_INFO("Dropping packet reception of packet with SF" << unsigned(spreadingFactor)
105 << " because we are in TX mode");
106 // Fire the trace source
107 m_noReceptionBecauseTransmitting(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
108 return;
109 }
110 // Check whether the gateway is configured to listen for the channel of the transmission
111 else if (!IsOnFrequency(frequencyHz))
112 {
113 // Unknown frequency
114 NS_LOG_INFO("Dropping packet reception of packet with SF"
115 << unsigned(spreadingFactor) << " because we are not listening to frequency "
116 << frequencyHz << " Hz");
117 /// TODO: implement trace source
118 return;
119 }
120 // Check modulation I/Q polarity (gateway PHYs listen for uplinks by default)
121 else if (iqPolarity != IQPolarity::UP)
122 {
123 NS_LOG_INFO("Dropping packet reception of packet with SF"
124 << unsigned(spreadingFactor)
125 << " because we are not listening to uplink transmissions");
126 /// TODO: implement trace source
127 return;
128 }
129 // See whether the reception power is above or below the sensitivity for that spreading factor
130 else if (double sens = SimpleGatewayLoraPhy::SENSITIVITY[spreadingFactor - 7];
131 rxPowerDbm < sens)
132 {
133 // Packet arrived below sensitivity
134 NS_LOG_INFO("Dropping packet reception of packet with SF"
135 << unsigned(spreadingFactor) << " because under the sensitivity of " << sens
136 << " dBm");
137 // Fire the trace source for this event.
138 m_underSensitivity(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
139 return;
140 }
141
142 // Cycle over the receive paths to check availability to receive the packet
143 for (auto& rxPath : m_receptionPaths)
144 {
145 // If the receive path is available and listening on the channel of
146 // interest, we have a candidate
147 if (rxPath->IsAvailable())
148 {
149 NS_LOG_INFO("Scheduling reception of a packet, occupying one demodulator");
150 // Block this resource
151 rxPath->LockOnEvent(event);
153 // Schedule the end of the reception of the packet
154 EventId endReceiveEventId = Simulator::Schedule(duration,
156 this,
157 packet,
158 event);
159 rxPath->SetEndReceive(endReceiveEventId);
160 // Fire the trace source
161 m_phyRxBeginTrace(packet);
162 return;
163 }
164 }
165
166 // If we get to this point, there are no demodulators we can use
167 NS_LOG_INFO("Dropping packet reception of packet with SF"
168 << unsigned(spreadingFactor) << " and frequency " << frequencyHz
169 << "Hz because no suitable demodulator was found");
170 // Fire the trace source
171 m_noMoreDemodulators(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
172}
173
174void
176{
177 NS_LOG_FUNCTION(this << packet << *event);
178
179 // Search for the demodulator that was locked on this event to free it.
180 for (auto& rxPath : m_receptionPaths)
181 {
182 if (rxPath->GetEvent() == event)
183 {
184 rxPath->Free();
186 continue;
187 }
188 }
189 // Call the trace source
190 m_phyRxEndTrace(packet);
191
192 // Call the LoraInterferenceHelper to determine whether there was destructive interference.
193 if (auto sf = m_interference.IsDestroyedByInterference(event); sf != 0)
194 {
195 NS_LOG_DEBUG("packetDestroyed by " << unsigned(sf));
196 // Update the packet's LoraTag
197 LoraTag tag;
198 packet->RemovePacketTag(tag);
199 tag.SetDestroyedBy(sf);
200 packet->AddPacketTag(tag);
201 // Fire the trace source
202 m_interferedPacket(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
203 return;
204 }
205
206 NS_LOG_INFO("Packet with SF " << unsigned(event->GetSpreadingFactor())
207 << " received correctly");
208 // Fire the trace source
209 m_successfullyReceivedPacket(packet, (m_device) ? m_device->GetNode()->GetId() : 0);
210
211 // Forward the packet to the upper layer
212 if (!m_rxOkCallback.IsNull())
213 {
214 // Set the receive power and frequency of this packet in the LoraTag: this information can
215 // be useful for upper layers trying to control link quality.
216 LoraTag tag;
217 packet->RemovePacketTag(tag);
218 tag.SetReceivePower(event->GetRxPowerDbm());
219 tag.SetFrequency(event->GetFrequency());
220 packet->AddPacketTag(tag);
221 m_rxOkCallback(packet);
222 }
223}
224
225} // namespace lorawan
226} // namespace ns3
An identifier for simulation events.
Definition event-id.h:45
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
GatewayLoraPhy()
Default constructor.
bool m_isTransmitting
Flag indicating whether a transmission is going on.
TracedValue< int > m_occupiedReceptionPaths
The number of occupied reception paths.
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
Internal call when transmission of a packet finishes.
static const double SENSITIVITY[6]
The sensitivity vector of this gateway to different SFs.
bool IsOnFrequency(uint32_t frequencyHz) const override
Implementation of LoraPhy's pure virtual function.
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...
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet reception ends.
Definition lora-phy.h:328
LoraInterferenceHelper m_interference
The LoraInterferenceHelper associated to this PHY.
Definition lora-phy.h:310
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:345
static Time GetTimeOnAir(uint32_t phyPayloadLen, const LoraTxParameters &txParams)
Compute the total transmission time for a physical packet based on modulation parameters.
Definition lora-phy.cc:110
TracedCallback< Ptr< const Packet >, uint32_t > m_successfullyReceivedPacket
The trace source fired when a packet was correctly received.
Definition lora-phy.h:333
TracedCallback< Ptr< const Packet >, uint32_t > m_startSending
The trace source fired when a packet is sent.
Definition lora-phy.h:317
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:339
Ptr< NetDevice > m_device
The net device this PHY is attached to.
Definition lora-phy.h:306
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition lora-phy.h:323
Ptr< LoraChannel > m_channel
The channel this PHY transmits on.
Definition lora-phy.h:308
RxOkCallback m_rxOkCallback
The callback to perform upon correct reception of a packet.
Definition lora-phy.h:297
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:26
void SetFrequency(uint32_t frequencyHz)
Set the frequency of the packet.
Definition lora-tag.cc:116
void SetReceivePower(double receivePower)
Set the power this packet was received with.
Definition lora-tag.cc:110
void SetDestroyedBy(uint8_t sf)
Set which Spreading Factor this packet was destroyed by.
Definition lora-tag.cc:98
Class modeling a Lora SX1301 chip.
static TypeId GetTypeId()
Register this type.
void StartReceive(Ptr< Packet > packet, uint32_t frequencyHz, IQPolarity iqPolarity, uint8_t spreadingFactor, double rxPowerDbm, Time duration) override
Start receiving a packet.
void EndReceive(Ptr< Packet > packet, Ptr< LoraInterferenceHelper::Event > event) override
Finish reception of a packet.
void Send(Ptr< Packet > packet, uint32_t frequencyHz, IQPolarity iqPolarity, const LoraTxParameters &txParams, double txPowerDbm) override
Instruct the PHY to send a packet according to some parameters.
#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
@ UP
Uplink / Upchirp / Normal polarity.
Definition lora-phy.h:34
#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:73