A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lora-packet-tracker.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 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 "ns3/lorawan-mac-header.h"
12#include "ns3/simulator.h"
13
14namespace ns3
15{
16namespace lorawan
17{
18NS_LOG_COMPONENT_DEFINE("LoraPacketTracker");
19
24
29
30/////////////////
31// MAC metrics //
32/////////////////
33
34void
36{
37 if (IsUplink(packet))
38 {
39 NS_LOG_INFO("A new packet was sent by the MAC layer");
40
41 MacPacketStatus status;
42 status.packet = packet;
43 status.sendTime = Now();
45 status.receivedTime = Time::Max();
46
47 m_macPacketTracker.insert(std::pair<Ptr<const Packet>, MacPacketStatus>(packet, status));
48 }
49}
50
51void
53 bool success,
54 Time firstAttempt,
55 Ptr<Packet> packet)
56{
57 NS_LOG_INFO("Finished retransmission attempts for a packet");
58 NS_LOG_DEBUG("Packet: " << packet << "ReqTx " << unsigned(reqTx) << ", succ: " << success
59 << ", firstAttempt: " << firstAttempt.As(Time::S));
60
62 entry.firstAttempt = firstAttempt;
63 entry.finishTime = Now();
64 entry.reTxAttempts = reqTx;
65 entry.successful = success;
66
67 m_reTransmissionTracker.insert(std::pair<Ptr<Packet>, RetransmissionStatus>(packet, entry));
68}
69
70void
72{
73 if (IsUplink(packet))
74 {
75 NS_LOG_INFO("A packet was successfully received at the MAC layer of gateway "
77
78 // Find the received packet in the m_macPacketTracker
79 auto it = m_macPacketTracker.find(packet);
80 if (it != m_macPacketTracker.end())
81 {
82 (*it).second.receptionTimes.insert(
83 std::pair<int, Time>(Simulator::GetContext(), Now()));
84 }
85 else
86 {
87 NS_ABORT_MSG("Packet not found in tracker");
88 }
89 }
90}
91
92/////////////////
93// PHY metrics //
94/////////////////
95
96void
98{
99 if (IsUplink(packet))
100 {
101 NS_LOG_INFO("PHY packet " << packet << " was transmitted by device " << edId);
102 // Create a packetStatus
103 PacketStatus status;
104 status.packet = packet;
105 status.sendTime = Now();
106 status.senderId = edId;
107
108 m_packetTracker.insert(std::pair<Ptr<const Packet>, PacketStatus>(packet, status));
109 }
110}
111
112void
114{
115 if (IsUplink(packet))
116 {
117 // Remove the successfully received packet from the list of sent ones
118 NS_LOG_INFO("PHY packet " << packet << " was successfully received at gateway " << gwId);
119
120 auto it = m_packetTracker.find(packet);
121 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, RECEIVED));
122 }
123}
124
125void
127{
128 if (IsUplink(packet))
129 {
130 NS_LOG_INFO("PHY packet " << packet << " was interfered at gateway " << gwId);
131
132 auto it = m_packetTracker.find(packet);
133 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, INTERFERED));
134 }
135}
136
137void
139{
140 if (IsUplink(packet))
141 {
142 NS_LOG_INFO("PHY packet " << packet << " was lost because no more receivers at gateway "
143 << gwId);
144 auto it = m_packetTracker.find(packet);
145 (*it).second.outcomes.insert(
146 std::pair<int, enum PhyPacketOutcome>(gwId, NO_MORE_RECEIVERS));
147 }
148}
149
150void
152{
153 if (IsUplink(packet))
154 {
155 NS_LOG_INFO("PHY packet " << packet << " was lost because under sensitivity at gateway "
156 << gwId);
157
158 auto it = m_packetTracker.find(packet);
159 (*it).second.outcomes.insert(
160 std::pair<int, enum PhyPacketOutcome>(gwId, UNDER_SENSITIVITY));
161 }
162}
163
164void
166{
167 if (IsUplink(packet))
168 {
170 "PHY packet " << packet
171 << " was lost because of concurrent downlink transmission at gateway "
172 << gwId);
173
174 auto it = m_packetTracker.find(packet);
175 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, LOST_BECAUSE_TX));
176 }
177}
178
179bool
181{
182 NS_LOG_FUNCTION(this);
183
184 LorawanMacHeader mHdr;
185 Ptr<Packet> copy = packet->Copy();
186 copy->RemoveHeader(mHdr);
187 return mHdr.IsUplink();
188}
189
190////////////////////////
191// Counting Functions //
192////////////////////////
193
194std::vector<int>
196{
197 // Vector packetCounts will contain - for the interval given in the input of
198 // the function, the following fields: totPacketsSent receivedPackets
199 // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets
200
201 std::vector<int> packetCounts(6, 0);
202
203 for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy)
204 {
205 if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime)
206 {
207 packetCounts.at(0)++;
208
209 NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet);
210 NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size()
211 << " gateways");
212
213 if ((*itPhy).second.outcomes.count(gwId) > 0)
214 {
215 switch ((*itPhy).second.outcomes.at(gwId))
216 {
217 case RECEIVED: {
218 packetCounts.at(1)++;
219 break;
220 }
221 case INTERFERED: {
222 packetCounts.at(2)++;
223 break;
224 }
225 case NO_MORE_RECEIVERS: {
226 packetCounts.at(3)++;
227 break;
228 }
229 case UNDER_SENSITIVITY: {
230 packetCounts.at(4)++;
231 break;
232 }
233 case LOST_BECAUSE_TX: {
234 packetCounts.at(5)++;
235 break;
236 }
237 case UNSET: {
238 break;
239 }
240 }
241 }
242 }
243 }
244
245 return packetCounts;
246}
247
248std::string
250{
251 // Vector packetCounts will contain - for the interval given in the input of
252 // the function, the following fields: totPacketsSent receivedPackets
253 // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets
254
255 std::vector<int> packetCounts(6, 0);
256
257 for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy)
258 {
259 if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime)
260 {
261 packetCounts.at(0)++;
262
263 NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet);
264 NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size()
265 << " gateways");
266
267 if ((*itPhy).second.outcomes.count(gwId) > 0)
268 {
269 switch ((*itPhy).second.outcomes.at(gwId))
270 {
271 case RECEIVED: {
272 packetCounts.at(1)++;
273 break;
274 }
275 case INTERFERED: {
276 packetCounts.at(2)++;
277 break;
278 }
279 case NO_MORE_RECEIVERS: {
280 packetCounts.at(3)++;
281 break;
282 }
283 case UNDER_SENSITIVITY: {
284 packetCounts.at(4)++;
285 break;
286 }
287 case LOST_BECAUSE_TX: {
288 packetCounts.at(5)++;
289 break;
290 }
291 case UNSET: {
292 break;
293 }
294 }
295 }
296 }
297 }
298
299 std::string output("");
300 for (int i = 0; i < 6; ++i)
301 {
302 output += std::to_string(packetCounts.at(i)) + " ";
303 }
304
305 return output;
306}
307
308std::string
310{
311 NS_LOG_FUNCTION(this << startTime << stopTime);
312
313 double sent = 0;
314 double received = 0;
315 for (auto it = m_macPacketTracker.begin(); it != m_macPacketTracker.end(); ++it)
316 {
317 if ((*it).second.sendTime >= startTime && (*it).second.sendTime <= stopTime)
318 {
319 sent++;
320 if (!(*it).second.receptionTimes.empty())
321 {
322 received++;
323 }
324 }
325 }
326
327 return std::to_string(sent) + " " + std::to_string(received);
328}
329
330std::string
332{
333 NS_LOG_FUNCTION(this << startTime << stopTime);
334
335 double sent = 0;
336 double received = 0;
337 for (auto it = m_reTransmissionTracker.begin(); it != m_reTransmissionTracker.end(); ++it)
338 {
339 if ((*it).second.firstAttempt >= startTime && (*it).second.firstAttempt <= stopTime)
340 {
341 sent++;
342 NS_LOG_DEBUG("Found a packet");
343 NS_LOG_DEBUG("Number of attempts: " << unsigned(it->second.reTxAttempts)
344 << ", successful: " << it->second.successful);
345 if (it->second.successful)
346 {
347 received++;
348 }
349 }
350 }
351
352 return std::to_string(sent) + " " + std::to_string(received);
353}
354
355} // namespace lorawan
356} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static uint32_t GetContext()
Get the current simulation context.
Definition simulator.cc:301
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
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition nstime.h:287
void NoMoreReceiversCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a gateway packet loss caused by lack of free reception paths.
void MacTransmissionCallback(Ptr< const Packet > packet)
Trace a packet leaving a node's MAC layer to go down the stack and be sent by the PHY layer.
PhyPacketData m_packetTracker
Packet map of PHY layer metrics.
void RequiredTransmissionsCallback(uint8_t reqTx, bool success, Time firstAttempt, Ptr< Packet > packet)
Trace the exit status of a MAC layer packet retransmission process of an end device.
void UnderSensitivityCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a gateway packet loss caused by signal strength under sensitivity.
void LostBecauseTxCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a gateway packet loss caused by concurrent downlink transmission.
std::vector< int > CountPhyPacketsPerGw(Time startTime, Time stopTime, int systemId)
Count packets in a time interval to evaluate the performance at PHY level of a specific gateway.
std::string PrintPhyPacketsPerGw(Time startTime, Time stopTime, int systemId)
Count packets in a time interval to evaluate the performance at PHY level of a specific gateway.
void MacGwReceptionCallback(Ptr< const Packet > packet)
Trace a packet leaving a gateway's MAC layer to go up the stack and be delivered to the node's applic...
LoraPacketTracker()
Default constructor.
void PacketReceptionCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a correct packet RX by the PHY layer of a gateway.
MacPacketData m_macPacketTracker
Packet map of MAC layer metrics.
std::string CountMacPacketsGlobally(Time startTime, Time stopTime)
In a time interval, count packets to evaluate the global performance at MAC level of the whole networ...
bool IsUplink(Ptr< const Packet > packet)
Check whether a packet is uplink.
void InterferenceCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a gateway packet loss caused by interference.
void TransmissionCallback(Ptr< const Packet > packet, uint32_t systemId)
Trace a packet TX start by the PHY layer of an end device.
RetransmissionData m_reTransmissionTracker
Packet map of retransmission process metrics.
std::string CountMacPacketsGloballyCpsr(Time startTime, Time stopTime)
In a time interval, count packets to evaluate the performance at MAC level of the whole network.
This class represents the Mac header of a LoRaWAN packet.
bool IsUplink() const
Check whether this header is for an uplink message.
Time stopTime
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#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
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition simulator.cc:288
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Stores MAC-layer packet metrics of sender/receivers.
Ptr< const Packet > packet
Packet being tracked.
Time receivedTime
Time of first reception (placeholder field).
Time sendTime
Timestamp of the pkt leaving MAC layer to go down the stack of sender.
uint32_t senderId
Node id of the packet sender.
Stores PHY-layer uplink packet metrics of sender/receivers.
uint32_t senderId
Node id of the packet sender.
Time sendTime
Timestamp of pkt radio tx start.
Ptr< const Packet > packet
Packet being tracked.
Stores (optionally enabled) MAC layer packet retransmission process metrics of end devices.
Time finishTime
Timestamp of the conclusion of the retransmission process.
Time firstAttempt
Timestamp of the first transmission attempt.
bool successful
Whether the retransmission procedure was successful.
uint8_t reTxAttempts
Number of transmissions attempted during the process.