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/log.h"
12#include "ns3/lorawan-mac-header.h"
13#include "ns3/simulator.h"
14
15#include <fstream>
16#include <iostream>
17
18namespace ns3
19{
20namespace lorawan
21{
22NS_LOG_COMPONENT_DEFINE("LoraPacketTracker");
23
28
33
34/////////////////
35// MAC metrics //
36/////////////////
37
38void
40{
41 if (IsUplink(packet))
42 {
43 NS_LOG_INFO("A new packet was sent by the MAC layer");
44
45 MacPacketStatus status;
46 status.packet = packet;
47 status.sendTime = Simulator::Now();
49 status.receivedTime = Time::Max();
50
51 m_macPacketTracker.insert(std::pair<Ptr<const Packet>, MacPacketStatus>(packet, status));
52 }
53}
54
55void
57 bool success,
58 Time firstAttempt,
59 Ptr<Packet> packet)
60{
61 NS_LOG_INFO("Finished retransmission attempts for a packet");
62 NS_LOG_DEBUG("Packet: " << packet << "ReqTx " << unsigned(reqTx) << ", succ: " << success
63 << ", firstAttempt: " << firstAttempt.GetSeconds());
64
66 entry.firstAttempt = firstAttempt;
67 entry.finishTime = Simulator::Now();
68 entry.reTxAttempts = reqTx;
69 entry.successful = success;
70
71 m_reTransmissionTracker.insert(std::pair<Ptr<Packet>, RetransmissionStatus>(packet, entry));
72}
73
74void
76{
77 if (IsUplink(packet))
78 {
79 NS_LOG_INFO("A packet was successfully received at the MAC layer of gateway "
81
82 // Find the received packet in the m_macPacketTracker
83 auto it = m_macPacketTracker.find(packet);
84 if (it != m_macPacketTracker.end())
85 {
86 (*it).second.receptionTimes.insert(
87 std::pair<int, Time>(Simulator::GetContext(), Simulator::Now()));
88 }
89 else
90 {
91 NS_ABORT_MSG("Packet not found in tracker");
92 }
93 }
94}
95
96/////////////////
97// PHY metrics //
98/////////////////
99
100void
102{
103 if (IsUplink(packet))
104 {
105 NS_LOG_INFO("PHY packet " << packet << " was transmitted by device " << edId);
106 // Create a packetStatus
107 PacketStatus status;
108 status.packet = packet;
109 status.sendTime = Simulator::Now();
110 status.senderId = edId;
111
112 m_packetTracker.insert(std::pair<Ptr<const Packet>, PacketStatus>(packet, status));
113 }
114}
115
116void
118{
119 if (IsUplink(packet))
120 {
121 // Remove the successfully received packet from the list of sent ones
122 NS_LOG_INFO("PHY packet " << packet << " was successfully received at gateway " << gwId);
123
124 auto it = m_packetTracker.find(packet);
125 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, RECEIVED));
126 }
127}
128
129void
131{
132 if (IsUplink(packet))
133 {
134 NS_LOG_INFO("PHY packet " << packet << " was interfered at gateway " << gwId);
135
136 auto it = m_packetTracker.find(packet);
137 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, INTERFERED));
138 }
139}
140
141void
143{
144 if (IsUplink(packet))
145 {
146 NS_LOG_INFO("PHY packet " << packet << " was lost because no more receivers at gateway "
147 << gwId);
148 auto it = m_packetTracker.find(packet);
149 (*it).second.outcomes.insert(
150 std::pair<int, enum PhyPacketOutcome>(gwId, NO_MORE_RECEIVERS));
151 }
152}
153
154void
156{
157 if (IsUplink(packet))
158 {
159 NS_LOG_INFO("PHY packet " << packet << " was lost because under sensitivity at gateway "
160 << gwId);
161
162 auto it = m_packetTracker.find(packet);
163 (*it).second.outcomes.insert(
164 std::pair<int, enum PhyPacketOutcome>(gwId, UNDER_SENSITIVITY));
165 }
166}
167
168void
170{
171 if (IsUplink(packet))
172 {
174 "PHY packet " << packet
175 << " was lost because of concurrent downlink transmission at gateway "
176 << gwId);
177
178 auto it = m_packetTracker.find(packet);
179 (*it).second.outcomes.insert(std::pair<int, enum PhyPacketOutcome>(gwId, LOST_BECAUSE_TX));
180 }
181}
182
183bool
185{
186 NS_LOG_FUNCTION(this);
187
188 LorawanMacHeader mHdr;
189 Ptr<Packet> copy = packet->Copy();
190 copy->RemoveHeader(mHdr);
191 return mHdr.IsUplink();
192}
193
194////////////////////////
195// Counting Functions //
196////////////////////////
197
198std::vector<int>
200{
201 // Vector packetCounts will contain - for the interval given in the input of
202 // the function, the following fields: totPacketsSent receivedPackets
203 // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets
204
205 std::vector<int> packetCounts(6, 0);
206
207 for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy)
208 {
209 if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime)
210 {
211 packetCounts.at(0)++;
212
213 NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet);
214 NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size()
215 << " gateways");
216
217 if ((*itPhy).second.outcomes.count(gwId) > 0)
218 {
219 switch ((*itPhy).second.outcomes.at(gwId))
220 {
221 case RECEIVED: {
222 packetCounts.at(1)++;
223 break;
224 }
225 case INTERFERED: {
226 packetCounts.at(2)++;
227 break;
228 }
229 case NO_MORE_RECEIVERS: {
230 packetCounts.at(3)++;
231 break;
232 }
233 case UNDER_SENSITIVITY: {
234 packetCounts.at(4)++;
235 break;
236 }
237 case LOST_BECAUSE_TX: {
238 packetCounts.at(5)++;
239 break;
240 }
241 case UNSET: {
242 break;
243 }
244 }
245 }
246 }
247 }
248
249 return packetCounts;
250}
251
252std::string
254{
255 // Vector packetCounts will contain - for the interval given in the input of
256 // the function, the following fields: totPacketsSent receivedPackets
257 // interferedPackets noMoreGwPackets underSensitivityPackets lostBecauseTxPackets
258
259 std::vector<int> packetCounts(6, 0);
260
261 for (auto itPhy = m_packetTracker.begin(); itPhy != m_packetTracker.end(); ++itPhy)
262 {
263 if ((*itPhy).second.sendTime >= startTime && (*itPhy).second.sendTime <= stopTime)
264 {
265 packetCounts.at(0)++;
266
267 NS_LOG_DEBUG("Dealing with packet " << (*itPhy).second.packet);
268 NS_LOG_DEBUG("This packet was received by " << (*itPhy).second.outcomes.size()
269 << " gateways");
270
271 if ((*itPhy).second.outcomes.count(gwId) > 0)
272 {
273 switch ((*itPhy).second.outcomes.at(gwId))
274 {
275 case RECEIVED: {
276 packetCounts.at(1)++;
277 break;
278 }
279 case INTERFERED: {
280 packetCounts.at(2)++;
281 break;
282 }
283 case NO_MORE_RECEIVERS: {
284 packetCounts.at(3)++;
285 break;
286 }
287 case UNDER_SENSITIVITY: {
288 packetCounts.at(4)++;
289 break;
290 }
291 case LOST_BECAUSE_TX: {
292 packetCounts.at(5)++;
293 break;
294 }
295 case UNSET: {
296 break;
297 }
298 }
299 }
300 }
301 }
302
303 std::string output("");
304 for (int i = 0; i < 6; ++i)
305 {
306 output += std::to_string(packetCounts.at(i)) + " ";
307 }
308
309 return output;
310}
311
312std::string
314{
315 NS_LOG_FUNCTION(this << startTime << stopTime);
316
317 double sent = 0;
318 double received = 0;
319 for (auto it = m_macPacketTracker.begin(); it != m_macPacketTracker.end(); ++it)
320 {
321 if ((*it).second.sendTime >= startTime && (*it).second.sendTime <= stopTime)
322 {
323 sent++;
324 if (!(*it).second.receptionTimes.empty())
325 {
326 received++;
327 }
328 }
329 }
330
331 return std::to_string(sent) + " " + std::to_string(received);
332}
333
334std::string
336{
337 NS_LOG_FUNCTION(this << startTime << stopTime);
338
339 double sent = 0;
340 double received = 0;
341 for (auto it = m_reTransmissionTracker.begin(); it != m_reTransmissionTracker.end(); ++it)
342 {
343 if ((*it).second.firstAttempt >= startTime && (*it).second.firstAttempt <= stopTime)
344 {
345 sent++;
346 NS_LOG_DEBUG("Found a packet");
347 NS_LOG_DEBUG("Number of attempts: " << unsigned(it->second.reTxAttempts)
348 << ", successful: " << it->second.successful);
349 if (it->second.successful)
350 {
351 received++;
352 }
353 }
354 }
355
356 return std::to_string(sent) + " " + std::to_string(received);
357}
358
359} // namespace lorawan
360} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static uint32_t GetContext()
Get the current simulation context.
Definition simulator.cc:307
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
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition nstime.h:286
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:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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
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.