A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
end-device-status.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 * Authors: Martina Capuzzo <capuzzom@dei.unipd.it>
7 * Davide Magrin <magrinda@dei.unipd.it>
8 */
9
10#include "end-device-status.h"
11
12#include "lora-frame-header.h"
13#include "lora-tag.h"
14#include "lorawan-mac-header.h"
15
16#include "ns3/command-line.h"
17#include "ns3/log.h"
18#include "ns3/packet.h"
19#include "ns3/pointer.h"
20#include "ns3/simulator.h"
21
22#include <algorithm>
23
24namespace ns3
25{
26namespace lorawan
27{
28
29NS_LOG_COMPONENT_DEFINE("EndDeviceStatus");
30
31TypeId
33{
34 static TypeId tid = TypeId("ns3::EndDeviceStatus")
36 .AddConstructor<EndDeviceStatus>()
37 .SetGroupName("lorawan");
38 return tid;
39}
40
43 : m_reply(EndDeviceStatus::Reply()),
44 m_endDeviceAddress(endDeviceAddress),
45 m_receivedPacketList(ReceivedPacketList()),
46 m_mac(endDeviceMac)
47{
48 NS_LOG_FUNCTION(endDeviceAddress);
49}
50
59
64
65///////////////
66// Getters //
67///////////////
68
69uint8_t
76
77double
84
85uint8_t
92
93double
99
102{
104
105 // Start from reply payload
106 Ptr<Packet> replyPacket;
107 if (m_reply.payload) // If it has APP data to send
108 {
109 NS_LOG_DEBUG("Crafting reply packet from existing payload");
110 replyPacket = m_reply.payload->Copy();
111 }
112 else // If no APP data needs to be sent, use an empty payload
113 {
114 NS_LOG_DEBUG("Crafting reply packet using an empty payload");
115 replyPacket = Create<Packet>(0);
116 }
117
118 // Add headers
121 LorawanMacHeader mHdr;
122 LoraFrameHeader fHdr;
123 fHdr.SetAsUplink();
124 lastPacket->RemoveHeader(mHdr);
125 lastPacket->RemoveHeader(fHdr);
128 replyPacket->AddHeader(m_reply.frameHeader);
129 replyPacket->AddHeader(m_reply.macHeader);
130
131 NS_LOG_DEBUG("Added MAC header" << m_reply.macHeader);
132 NS_LOG_DEBUG("Added frame header" << m_reply.frameHeader);
133
134 return replyPacket;
135}
136
137bool
144
151
158
165
168{
169 return m_mac;
170}
171
178
179void
185
186void
192
193void
199
200void
206
207void
213
214void
220
221void
223{
225 m_reply.payload = replyPayload;
226}
227
228///////////////////////
229// Other methods //
230///////////////////////
231
232void
234{
236
237 // Create a copy of the packet
238 Ptr<Packet> myPacket = receivedPacket->Copy();
239
240 // Extract the headers
241 LorawanMacHeader macHdr;
242 myPacket->RemoveHeader(macHdr);
243
244 LoraFrameHeader frameHdr;
245 frameHdr.SetAsUplink();
246 myPacket->RemoveHeader(frameHdr);
247
248 // Update current parameters
249 LoraTag tag;
250 myPacket->RemovePacketTag(tag);
253
254 // Update Information on the received packet
256 info.sf = tag.GetSpreadingFactor();
257 info.frequency = tag.GetFrequency();
258 info.packet = receivedPacket;
259
260 double rcvPower = tag.GetReceivePower();
261
262 // Perform insertion in list, also checking that the packet isn't already in
263 // the list (it could have been already received by another gateway)
264
265 // Start searching from the end
266 auto it = m_receivedPacketList.rbegin();
267 for (; it != m_receivedPacketList.rend(); it++)
268 {
269 // Get the frame counter of the current packet to compare it with the
270 // newly received one
271 Ptr<Packet> packetCopy = ((*it).first)->Copy();
272 LorawanMacHeader currentMacHdr;
273 packetCopy->RemoveHeader(currentMacHdr);
274 LoraFrameHeader currentFrameHdr;
275 frameHdr.SetAsUplink();
276 packetCopy->RemoveHeader(currentFrameHdr);
277
278 NS_LOG_DEBUG("Received packet's frame counter: " << unsigned(frameHdr.GetFCnt())
279 << "\nCurrent packet's frame counter: "
280 << unsigned(currentFrameHdr.GetFCnt()));
281
282 if (frameHdr.GetFCnt() == currentFrameHdr.GetFCnt())
283 {
284 NS_LOG_INFO("Packet was already received by another gateway");
285
286 // This packet had already been received from another gateway:
287 // add this gateway's reception information.
288 GatewayList& gwList = it->second.gwList;
289
290 PacketInfoPerGw gwInfo;
291 gwInfo.receivedTime = Simulator::Now();
292 gwInfo.rxPower = rcvPower;
293 gwInfo.gwAddress = gwAddress;
294 gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
295
296 NS_LOG_DEBUG("Size of gateway list: " << gwList.size());
297
298 break; // Exit from the cycle
299 }
300 }
301 if (it == m_receivedPacketList.rend())
302 {
303 NS_LOG_INFO("Packet was received for the first time");
304 PacketInfoPerGw gwInfo;
305 gwInfo.receivedTime = Simulator::Now();
306 gwInfo.rxPower = rcvPower;
307 gwInfo.gwAddress = gwAddress;
308 info.gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
309 m_receivedPacketList.emplace_back(receivedPacket, info);
310 }
311 NS_LOG_DEBUG(*this);
312}
313
316{
318 auto it = m_receivedPacketList.rbegin();
319 if (it != m_receivedPacketList.rend())
320 {
321 return it->second;
322 }
323 else
324 {
326 }
327}
328
331{
333 auto it = m_receivedPacketList.rbegin();
334 if (it != m_receivedPacketList.rend())
335 {
336 return it->first;
337 }
338 else
339 {
340 return nullptr;
341 }
342}
343
344void
351
352void
357
358bool
363
364void
369
370void
375
376std::map<double, Address>
378{
379 // Create a map of the gateways
380 // Key: received power
381 // Value: address of the corresponding gateway
382 ReceivedPacketInfo info = m_receivedPacketList.back().second;
383 GatewayList gwList = info.gwList;
384
385 std::map<double, Address> gatewayPowers;
386
387 for (auto it = gwList.begin(); it != gwList.end(); it++)
388 {
389 Address currentGwAddress = (*it).first;
390 double currentRxPower = (*it).second.rxPower;
391 gatewayPowers.insert(std::pair<double, Address>(currentRxPower, currentGwAddress));
392 }
393
394 return gatewayPowers;
395}
396
397std::ostream&
398operator<<(std::ostream& os, const EndDeviceStatus& status)
399{
400 os << "Total packets received: " << status.m_receivedPacketList.size() << std::endl;
401
402 for (auto j = status.m_receivedPacketList.begin(); j != status.m_receivedPacketList.end(); j++)
403 {
404 EndDeviceStatus::ReceivedPacketInfo info = (*j).second;
405 EndDeviceStatus::GatewayList gatewayList = info.gwList;
406 Ptr<const Packet> pkt = (*j).first;
407 os << pkt << " " << gatewayList.size() << std::endl;
408 for (auto k = gatewayList.begin(); k != gatewayList.end(); k++)
409 {
410 EndDeviceStatus::PacketInfoPerGw infoPerGw = (*k).second;
411 os << " " << infoPerGw.gwAddress << " " << infoPerGw.rxPower << std::endl;
412 }
413 }
414
415 return os;
416}
417} // namespace lorawan
418} // namespace ns3
a polymophic address class
Definition address.h:90
An identifier for simulation events.
Definition event-id.h:45
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
A base class which provides memory management and object aggregation.
Definition object.h:78
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition packet.cc:120
Smart pointer class similar to boost::intrusive_ptr.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition simulator.cc:274
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
This class represents the network server's knowledge about an end device in the LoRaWAN network it is...
EndDeviceStatus::ReceivedPacketInfo GetLastReceivedPacketInfo()
Return the information about the last packet that was received from the device.
void SetFirstReceiveWindowFrequency(double frequency)
Set the first window frequency of this device.
void SetSecondReceiveWindowFrequency(double frequency)
Set the second window frequency of this device.
uint8_t m_secondReceiveWindowSpreadingFactor
Spreading Factor (SF) for RX2 window.
bool HasReceiveWindowOpportunityScheduled()
Check if there is already a running reception window event scheduled for this end device.
void SetReplyMacHeader(LorawanMacHeader macHeader)
Set the reply packet mac header.
void SetReplyFrameHeader(LoraFrameHeader frameHeader)
Set the reply packet frame header.
double m_firstReceiveWindowFrequency
Frequency [MHz] for RX1 window.
static TypeId GetTypeId()
Register this type.
Ptr< Packet > GetReplyPayload()
Get the data of the reply packet.
std::list< std::pair< Ptr< const Packet >, ReceivedPacketInfo > > ReceivedPacketList
typedef of a list of packets paired to their reception info.
void SetSecondReceiveWindowSpreadingFactor(uint8_t sf)
Set the spreading factor this device is using in the second receive window.
LorawanMacHeader GetReplyMacHeader() const
Get the reply packet mac header.
uint8_t m_firstReceiveWindowSpreadingFactor
Spreading Factor (SF) for RX1 window.
void InsertReceivedPacket(Ptr< const Packet > receivedPacket, const Address &gwAddress)
Insert a received packet in the packet list.
EventId m_receiveWindowEvent
Event storing the next scheduled downlink transmission.
struct Reply m_reply
Next reply intended for this device.
LoraDeviceAddress m_endDeviceAddress
The address of this device.
bool NeedsReply() const
Whether the end device needs a reply.
LoraFrameHeader GetReplyFrameHeader() const
Get the reply packet frame header.
double m_secondReceiveWindowFrequency
Frequency [MHz] for RX2 window.
double GetSecondReceiveWindowFrequency() const
Return the second window frequency of this device.
std::map< Address, PacketInfoPerGw > GatewayList
typedef of a list of gateways with relative reception information.
ReceivedPacketList m_receivedPacketList
List of received packets.
void RemoveReceiveWindowOpportunity()
Cancel next scheduled reception window event.
void SetReceiveWindowOpportunity(EventId event)
Store next scheduled reception window event.
ReceivedPacketList GetReceivedPacketList() const
Get the received packet list.
double GetFirstReceiveWindowFrequency() const
Get the first window frequency of this device.
Ptr< const Packet > GetLastPacketReceivedFromDevice()
Return the last packet that was received from this device.
void SetReplyPayload(Ptr< Packet > replyPayload)
Set the packet reply payload.
void AddMACCommand(Ptr< MacCommand > macCommand)
Add MAC command to the frame header of next reply.
uint8_t GetFirstReceiveWindowSpreadingFactor() const
Get the spreading factor this device is using in the first receive window.
void SetFirstReceiveWindowSpreadingFactor(uint8_t sf)
Set the spreading factor this device is using in the first receive window.
Ptr< ClassAEndDeviceLorawanMac > m_mac
Pointer to the MAC layer of this device.
void InitializeReply()
Reset the next reply state.
std::map< double, Address > GetPowerGatewayMap()
Get the gateways which received the last packet from the end device.
uint8_t GetSecondReceiveWindowSpreadingFactor() const
Get the spreading factor this device is using in the second receive window.
Ptr< Packet > GetCompleteReplyPacket()
Get the reply packet.
~EndDeviceStatus() override
Destructor.
EndDeviceStatus()
Default constructor.
Ptr< ClassAEndDeviceLorawanMac > GetMac()
Get the MAC layer of the end device.
This class represents the device address of a LoraWAN end device.
This class represents the Frame header (FHDR) used in a LoraWAN network.
void AddCommand(Ptr< MacCommand > macCommand)
Add a predefined command to the list in this frame header.
void SetFCnt(uint16_t fCnt)
Set the FCnt value.
void SetAddress(LoraDeviceAddress address)
Set the address.
uint16_t GetFCnt() const
Get the FCnt value.
void SetAsUplink()
State that this is an uplink message.
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:26
double GetReceivePower() const
Read the power this packet arrived with.
Definition lora-tag.cc:95
uint8_t GetSpreadingFactor() const
Read which Spreading Factor this packet was transmitted with.
Definition lora-tag.cc:83
double GetFrequency() const
Get the frequency of the packet.
Definition lora-tag.cc:125
This class represents the Mac header of a LoRaWAN packet.
void SetMType(enum MType mtype)
Set the message type.
#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_NOARGS()
Output the name of the function.
#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
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
std::ostream & operator<<(std::ostream &os, const EndDeviceStatus &status)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition ptr.h:604
Structure saving information regarding the packet reception in each gateway.
Time receivedTime
Time at which the packet was received by this gateway.
Address gwAddress
Address of the gateway that received the packet.
double rxPower
Reception power of the packet at this gateway.
Structure saving information regarding all packet receptions.
GatewayList gwList
List of gateways that received this packet.
double frequency
Carrier frequency [MHz] used to send this packet.
Ptr< const Packet > packet
The received packet.
uint8_t sf
Spreading factor used to send this packet.
Structure representing the reply that the network server will send this device at the first opportuni...
LorawanMacHeader macHeader
The MAC Header to attach to the reply packet.
bool needsReply
Whether or not this device needs a reply.
Ptr< Packet > payload
The data packet that will be sent as a reply.
LoraFrameHeader frameHeader
The Frame Header to attach to the reply packet.