A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
simple-end-device-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
16#include <algorithm>
17
18namespace ns3
19{
20namespace lorawan
21{
22
23NS_LOG_COMPONENT_DEFINE("SimpleEndDeviceLoraPhy");
24
26
27TypeId
29{
30 static TypeId tid = TypeId("ns3::SimpleEndDeviceLoraPhy")
32 .SetGroupName("lorawan")
33 .AddConstructor<SimpleEndDeviceLoraPhy>();
34
35 return tid;
36}
37
38// Initialize the device with some common settings.
39// These will then be changed by helpers.
43
47
48void
50 LoraTxParameters txParams,
51 uint32_t frequencyHz,
52 double txPowerDbm)
53{
54 NS_LOG_FUNCTION(this << packet << txParams << frequencyHz << txPowerDbm);
55
56 NS_LOG_INFO("Current state: " << m_state);
57
58 // We must be either in STANDBY or SLEEP mode to send a packet
59 if (m_state != STANDBY && m_state != SLEEP)
60 {
61 NS_LOG_INFO("Cannot send because device is currently not in STANDBY or SLEEP mode");
62 return;
63 }
64
65 // Compute the duration of the transmission
66 Time duration = GetOnAirTime(packet, txParams);
67
68 // We can send the packet: switch to the TX state
69 SwitchToTx(txPowerDbm);
70
71 // Tag the packet with information about its Spreading Factor
72 LoraTag tag;
73 packet->RemovePacketTag(tag);
74 tag.SetSpreadingFactor(txParams.sf);
75 packet->AddPacketTag(tag);
76
77 // Send the packet over the channel
78 NS_LOG_INFO("Sending the packet in the channel");
79 m_channel->Send(this, packet, txPowerDbm, txParams, duration, frequencyHz);
80
81 // Schedule a call to signal the transmission end.
83
84 // Call the trace source
85 if (m_device)
86 {
87 m_startSending(packet, m_device->GetNode()->GetId());
88 }
89 else
90 {
91 m_startSending(packet, 0);
92 }
93}
94
95void
97 double rxPowerDbm,
98 uint8_t sf,
99 Time duration,
100 uint32_t frequencyHz)
101{
102 NS_LOG_FUNCTION(this << packet << rxPowerDbm << unsigned(sf) << duration << frequencyHz);
103
104 // Notify the LoraInterferenceHelper of the impinging signal, and remember
105 // the event it creates. This will be used then to correctly handle the end
106 // of reception event.
107 //
108 // We need to do this regardless of our state or frequency, since these could
109 // change (and making the interference relevant) while the interference is
110 // still incoming.
111
113 event = m_interference.Add(duration, rxPowerDbm, sf, packet, frequencyHz);
114
115 // Switch on the current PHY state
116 switch (m_state)
117 {
118 // In the SLEEP, TX and RX cases we cannot receive the packet: we only add
119 // it to the list of interferers and do not schedule an EndReceive event for
120 // it.
121 case SLEEP: {
122 NS_LOG_INFO("Dropping packet because device is in SLEEP state");
123 break;
124 }
125 case TX: {
126 NS_LOG_INFO("Dropping packet because device is in TX state");
127 break;
128 }
129 case RX: {
130 NS_LOG_INFO("Dropping packet because device is already in RX state");
131 break;
132 }
133 // If we are in STANDBY mode, we can potentially lock on the currently
134 // incoming transmission
135 case STANDBY: {
136 // There are a series of properties the packet needs to respect in order
137 // for us to be able to lock on it:
138 // - It's on frequency we are listening on
139 // - It uses the spreading factor we are configured to look for
140 // - Its receive power is above the device sensitivity for that spreading factor
141
142 // Flag to signal whether we can receive the packet or not
143 bool canLockOnPacket = true;
144
145 // Save needed sensitivity
146 double sensitivity = EndDeviceLoraPhy::sensitivity[unsigned(sf) - 7];
147
148 // Check frequency
149 //////////////////
150 if (!IsOnFrequency(frequencyHz))
151 {
152 NS_LOG_INFO("Packet lost because it's on frequency "
153 << frequencyHz << " Hz and we are listening at " << m_frequencyHz << " Hz");
154
155 // Fire the trace source for this event.
156 if (m_device)
157 {
158 m_wrongFrequency(packet, m_device->GetNode()->GetId());
159 }
160 else
161 {
162 m_wrongFrequency(packet, 0);
163 }
164
165 canLockOnPacket = false;
166 }
167
168 // Check Spreading Factor
169 /////////////////////////
170 if (sf != m_sf)
171 {
172 NS_LOG_INFO("Packet lost because it's using SF"
173 << unsigned(sf) << ", while we are listening for SF" << unsigned(m_sf));
174
175 // Fire the trace source for this event.
176 if (m_device)
177 {
178 m_wrongSf(packet, m_device->GetNode()->GetId());
179 }
180 else
181 {
182 m_wrongSf(packet, 0);
183 }
184
185 canLockOnPacket = false;
186 }
187
188 // Check Sensitivity
189 ////////////////////
190 if (rxPowerDbm < sensitivity)
191 {
192 NS_LOG_INFO("Dropping packet reception of packet with sf = "
193 << unsigned(sf) << " because under the sensitivity of " << sensitivity
194 << " dBm");
195
196 // Fire the trace source for this event.
197 if (m_device)
198 {
199 m_underSensitivity(packet, m_device->GetNode()->GetId());
200 }
201 else
202 {
203 m_underSensitivity(packet, 0);
204 }
205
206 canLockOnPacket = false;
207 }
208
209 // Check if one of the above failed
210 ///////////////////////////////////
211 if (canLockOnPacket)
212 {
213 // Switch to RX state
214 // EndReceive will handle the switch back to STANDBY state
215 SwitchToRx();
216
217 // Schedule the end of the reception of the packet
218 NS_LOG_INFO("Scheduling reception of a packet. End in " << duration.As(Time::S));
219
220 Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event);
221
222 // Fire the beginning of reception trace source
223 m_phyRxBeginTrace(packet);
224 }
225 }
226 }
227}
228
229void
231{
232 NS_LOG_FUNCTION(this << packet << event);
233
234 // Automatically switch to Standby in either case
236
237 // Fire the trace source
238 m_phyRxEndTrace(packet);
239
240 // Call the LoraInterferenceHelper to determine whether there was destructive
241 // interference on this event.
242 bool packetDestroyed = m_interference.IsDestroyedByInterference(event);
243
244 // Fire the trace source if packet was destroyed
245 if (packetDestroyed)
246 {
247 NS_LOG_INFO("Packet destroyed by interference");
248
249 if (m_device)
250 {
251 m_interferedPacket(packet, m_device->GetNode()->GetId());
252 }
253 else
254 {
255 m_interferedPacket(packet, 0);
256 }
257
258 // If there is one, perform the callback to inform the upper layer of the
259 // lost packet
260 if (!m_rxFailedCallback.IsNull())
261 {
262 m_rxFailedCallback(packet);
263 }
264 }
265 else
266 {
267 NS_LOG_INFO("Packet received correctly");
268
269 if (m_device)
270 {
271 m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId());
272 }
273 else
274 {
276 }
277
278 // If there is one, perform the callback to inform the upper layer
279 if (!m_rxOkCallback.IsNull())
280 {
281 LoraTag tag;
282 packet->RemovePacketTag(tag);
283 tag.SetReceivePower(event->GetRxPowerdBm());
284 tag.SetFrequency(event->GetFrequency());
285 packet->AddPacketTag(tag);
286 m_rxOkCallback(packet);
287 }
288 }
289}
290} // namespace lorawan
291} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:403
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
static const double sensitivity[6]
The sensitivity vector of this device to different SFs.
uint8_t m_sf
The Spreading Factor this device is listening for.
bool IsOnFrequency(uint32_t frequencyHz) override
Whether this device is listening on the specified frequency or not.
void SwitchToRx()
Switch to the RX state.
void SwitchToStandby()
Switch to the STANDBY state.
EndDeviceLoraPhy()
Default constructor.
uint32_t m_frequencyHz
The frequency [Hz] this device is listening on.
TracedValue< State > m_state
The state this PHY is currently in.
TracedCallback< Ptr< const Packet >, uint32_t > m_wrongSf
Trace source for when a packet is lost because it was using a spreading factor different from the one...
void SwitchToTx(double txPowerDbm)
Switch to the TX state.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ SLEEP
The PHY layer is sleeping.
@ STANDBY
The PHY layer is in STANDBY.
void TxFinished(Ptr< const Packet > packet) override
Signals the end of a transmission by the EndDeviceLoraPhy.
TracedCallback< Ptr< const Packet >, uint32_t > m_wrongFrequency
Trace source for when a packet is lost because it was transmitted on a frequency different from the o...
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
RxFailedCallback m_rxFailedCallback
The callback to perform upon failed reception of a packet we were locked on.
Definition lora-phy.h:325
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(uint32_t frequencyHz)
Set the frequency of the packet.
Definition lora-tag.cc:119
void SetSpreadingFactor(uint8_t sf)
Set which Spreading Factor this packet was transmitted with.
Definition lora-tag.cc:107
void SetReceivePower(double receivePower)
Set the power this packet was received with.
Definition lora-tag.cc:113
Class representing a simple LoRa transceiver, with an error model based on receiver sensitivity and a...
void Send(Ptr< Packet > packet, LoraTxParameters txParams, uint32_t frequencyHz, 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, uint32_t frequencyHz) 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_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