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