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
25NS_OBJECT_ENSURE_REGISTERED(SimpleEndDeviceLoraPhy);
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 double frequencyMHz,
52 double txPowerDbm)
53{
54 NS_LOG_FUNCTION(this << packet << txParams << frequencyMHz << 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, frequencyMHz);
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 double frequencyMHz)
101{
102 NS_LOG_FUNCTION(this << packet << rxPowerDbm << unsigned(sf) << duration << frequencyMHz);
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, frequencyMHz);
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(frequencyMHz))
151 {
152 NS_LOG_INFO("Packet lost because it's on frequency "
153 << frequencyMHz << " MHz and we are listening at " << m_frequency
154 << " MHz");
155
156 // Fire the trace source for this event.
157 if (m_device)
158 {
159 m_wrongFrequency(packet, m_device->GetNode()->GetId());
160 }
161 else
162 {
163 m_wrongFrequency(packet, 0);
164 }
165
166 canLockOnPacket = false;
167 }
168
169 // Check Spreading Factor
170 /////////////////////////
171 if (sf != m_sf)
172 {
173 NS_LOG_INFO("Packet lost because it's using SF"
174 << unsigned(sf) << ", while we are listening for SF" << unsigned(m_sf));
175
176 // Fire the trace source for this event.
177 if (m_device)
178 {
179 m_wrongSf(packet, m_device->GetNode()->GetId());
180 }
181 else
182 {
183 m_wrongSf(packet, 0);
184 }
185
186 canLockOnPacket = false;
187 }
188
189 // Check Sensitivity
190 ////////////////////
191 if (rxPowerDbm < sensitivity)
192 {
193 NS_LOG_INFO("Dropping packet reception of packet with sf = "
194 << unsigned(sf) << " because under the sensitivity of " << sensitivity
195 << " dBm");
196
197 // Fire the trace source for this event.
198 if (m_device)
199 {
200 m_underSensitivity(packet, m_device->GetNode()->GetId());
201 }
202 else
203 {
204 m_underSensitivity(packet, 0);
205 }
206
207 canLockOnPacket = false;
208 }
209
210 // Check if one of the above failed
211 ///////////////////////////////////
212 if (canLockOnPacket)
213 {
214 // Switch to RX state
215 // EndReceive will handle the switch back to STANDBY state
216 SwitchToRx();
217
218 // Schedule the end of the reception of the packet
219 NS_LOG_INFO("Scheduling reception of a packet. End in " << duration.GetSeconds()
220 << " seconds");
221
222 Simulator::Schedule(duration, &LoraPhy::EndReceive, this, packet, event);
223
224 // Fire the beginning of reception trace source
225 m_phyRxBeginTrace(packet);
226 }
227 }
228 }
229}
230
231void
233{
234 NS_LOG_FUNCTION(this << packet << event);
235
236 // Automatically switch to Standby in either case
238
239 // Fire the trace source
240 m_phyRxEndTrace(packet);
241
242 // Call the LoraInterferenceHelper to determine whether there was destructive
243 // interference on this event.
244 bool packetDestroyed = m_interference.IsDestroyedByInterference(event);
245
246 // Fire the trace source if packet was destroyed
247 if (packetDestroyed)
248 {
249 NS_LOG_INFO("Packet destroyed by interference");
250
251 if (m_device)
252 {
253 m_interferedPacket(packet, m_device->GetNode()->GetId());
254 }
255 else
256 {
257 m_interferedPacket(packet, 0);
258 }
259
260 // If there is one, perform the callback to inform the upper layer of the
261 // lost packet
263 {
264 m_rxFailedCallback(packet);
265 }
266 }
267 else
268 {
269 NS_LOG_INFO("Packet received correctly");
270
271 if (m_device)
272 {
273 m_successfullyReceivedPacket(packet, m_device->GetNode()->GetId());
274 }
275 else
276 {
278 }
279
280 // If there is one, perform the callback to inform the upper layer
281 if (!m_rxOkCallback.IsNull())
282 {
283 m_rxOkCallback(packet);
284 }
285 }
286}
287} // namespace lorawan
288} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition callback.h:555
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
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
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 representing a LoRa transceiver.
bool IsOnFrequency(double frequencyMHz) override
Whether this device is listening on the specified frequency or not.
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.
void SwitchToRx()
Switch to the RX state.
void SwitchToStandby()
Switch to the STANDBY state.
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.
double m_frequency
The frequency this device is listening on.
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...
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
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 SetSpreadingFactor(uint8_t sf)
Set which Spreading Factor this packet was transmitted with.
Definition lora-tag.cc:107
Class representing a simple LoRa transceiver, with an error model based on receiver sensitivity and a...
void StartReceive(Ptr< Packet > packet, double rxPowerDbm, uint8_t sf, Time duration, double frequencyMHz) override
Start receiving a packet.
static TypeId GetTypeId()
Register this type.
void Send(Ptr< Packet > packet, LoraTxParameters txParams, double frequencyMHz, double txPowerDbm) override
Instruct the PHY to send a packet according to some parameters.
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