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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Martina Capuzzo <capuzzom@dei.unipd.it>
18 * Davide Magrin <magrinda@dei.unipd.it>
19 */
20
21#include "end-device-status.h"
22
23#include "lora-frame-header.h"
24#include "lora-tag.h"
25#include "lorawan-mac-header.h"
26
27#include "ns3/command-line.h"
28#include "ns3/log.h"
29#include "ns3/packet.h"
30#include "ns3/pointer.h"
31#include "ns3/simulator.h"
32
33#include <algorithm>
34
35namespace ns3
36{
37namespace lorawan
38{
39
40NS_LOG_COMPONENT_DEFINE("EndDeviceStatus");
41
42TypeId
44{
45 static TypeId tid = TypeId("ns3::EndDeviceStatus")
47 .AddConstructor<EndDeviceStatus>()
48 .SetGroupName("lorawan");
49 return tid;
50}
51
54 : m_reply(EndDeviceStatus::Reply()),
55 m_endDeviceAddress(endDeviceAddress),
56 m_receivedPacketList(ReceivedPacketList()),
57 m_mac(endDeviceMac)
58{
59 NS_LOG_FUNCTION(endDeviceAddress);
60}
61
63{
65
66 // Initialize data structure
69}
70
72{
74}
75
76///////////////
77// Getters //
78///////////////
79
80uint8_t
82{
84
86}
87
88double
90{
92
94}
95
96uint8_t
98{
100
102}
103
104double
106{
109}
110
113{
115
116 // Start from reply payload
117 Ptr<Packet> replyPacket;
118 if (m_reply.payload) // If it has APP data to send
119 {
120 NS_LOG_DEBUG("Crafting reply packet from existing payload");
121 replyPacket = m_reply.payload->Copy();
122 }
123 else // If no APP data needs to be sent, use an empty payload
124 {
125 NS_LOG_DEBUG("Crafting reply packet using an empty payload");
126 replyPacket = Create<Packet>(0);
127 }
128
129 // Add headers
132 LorawanMacHeader mHdr;
133 LoraFrameHeader fHdr;
134 fHdr.SetAsUplink();
135 lastPacket->RemoveHeader(mHdr);
136 lastPacket->RemoveHeader(fHdr);
139 replyPacket->AddHeader(m_reply.frameHeader);
140 replyPacket->AddHeader(m_reply.macHeader);
141
142 NS_LOG_DEBUG("Added MAC header" << m_reply.macHeader);
143 NS_LOG_DEBUG("Added frame header" << m_reply.frameHeader);
144
145 return replyPacket;
146}
147
148bool
150{
152
153 return m_reply.needsReply;
154}
155
158{
160 return m_reply.macHeader;
161}
162
165{
167 return m_reply.frameHeader;
168}
169
172{
174 return m_reply.payload->Copy();
175}
176
179{
180 return m_mac;
181}
182
185{
188}
189
190void
192{
195}
196
197void
199{
202}
203
204void
206{
209}
210
211void
213{
216}
217
218void
220{
222 m_reply.macHeader = macHeader;
223}
224
225void
227{
229 m_reply.frameHeader = frameHeader;
230}
231
232void
234{
236 m_reply.payload = replyPayload;
237}
238
239///////////////////////
240// Other methods //
241///////////////////////
242
243void
245{
247
248 // Create a copy of the packet
249 Ptr<Packet> myPacket = receivedPacket->Copy();
250
251 // Extract the headers
252 LorawanMacHeader macHdr;
253 myPacket->RemoveHeader(macHdr);
254
255 LoraFrameHeader frameHdr;
256 frameHdr.SetAsUplink();
257 myPacket->RemoveHeader(frameHdr);
258
259 // Update current parameters
260 LoraTag tag;
261 myPacket->RemovePacketTag(tag);
264
265 // Update Information on the received packet
267 info.sf = tag.GetSpreadingFactor();
268 info.frequency = tag.GetFrequency();
269 info.packet = receivedPacket;
270
271 double rcvPower = tag.GetReceivePower();
272
273 // Perform insertion in list, also checking that the packet isn't already in
274 // the list (it could have been already received by another gateway)
275
276 // Start searching from the end
277 auto it = m_receivedPacketList.rbegin();
278 for (; it != m_receivedPacketList.rend(); it++)
279 {
280 // Get the frame counter of the current packet to compare it with the
281 // newly received one
282 Ptr<Packet> packetCopy = ((*it).first)->Copy();
283 LorawanMacHeader currentMacHdr;
284 packetCopy->RemoveHeader(currentMacHdr);
285 LoraFrameHeader currentFrameHdr;
286 frameHdr.SetAsUplink();
287 packetCopy->RemoveHeader(currentFrameHdr);
288
289 NS_LOG_DEBUG("Received packet's frame counter: " << unsigned(frameHdr.GetFCnt())
290 << "\nCurrent packet's frame counter: "
291 << unsigned(currentFrameHdr.GetFCnt()));
292
293 if (frameHdr.GetFCnt() == currentFrameHdr.GetFCnt())
294 {
295 NS_LOG_INFO("Packet was already received by another gateway");
296
297 // This packet had already been received from another gateway:
298 // add this gateway's reception information.
299 GatewayList& gwList = it->second.gwList;
300
301 PacketInfoPerGw gwInfo;
302 gwInfo.receivedTime = Simulator::Now();
303 gwInfo.rxPower = rcvPower;
304 gwInfo.gwAddress = gwAddress;
305 gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
306
307 NS_LOG_DEBUG("Size of gateway list: " << gwList.size());
308
309 break; // Exit from the cycle
310 }
311 }
312 if (it == m_receivedPacketList.rend())
313 {
314 NS_LOG_INFO("Packet was received for the first time");
315 PacketInfoPerGw gwInfo;
316 gwInfo.receivedTime = Simulator::Now();
317 gwInfo.rxPower = rcvPower;
318 gwInfo.gwAddress = gwAddress;
319 info.gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
320 m_receivedPacketList.emplace_back(receivedPacket, info);
321 }
322 NS_LOG_DEBUG(*this);
323}
324
327{
329 auto it = m_receivedPacketList.rbegin();
330 if (it != m_receivedPacketList.rend())
331 {
332 return it->second;
333 }
334 else
335 {
337 }
338}
339
342{
344 auto it = m_receivedPacketList.rbegin();
345 if (it != m_receivedPacketList.rend())
346 {
347 return it->first;
348 }
349 else
350 {
351 return nullptr;
352 }
353}
354
355void
357{
359 m_reply = Reply();
360 m_reply.needsReply = false;
361}
362
363void
365{
366 m_reply.frameHeader.AddCommand(macCommand);
367}
368
369bool
371{
373}
374
375void
377{
378 m_receiveWindowEvent = event;
379}
380
381void
383{
385}
386
387std::map<double, Address>
389{
390 // Create a map of the gateways
391 // Key: received power
392 // Value: address of the corresponding gateway
393 ReceivedPacketInfo info = m_receivedPacketList.back().second;
394 GatewayList gwList = info.gwList;
395
396 std::map<double, Address> gatewayPowers;
397
398 for (auto it = gwList.begin(); it != gwList.end(); it++)
399 {
400 Address currentGwAddress = (*it).first;
401 double currentRxPower = (*it).second.rxPower;
402 gatewayPowers.insert(std::pair<double, Address>(currentRxPower, currentGwAddress));
403 }
404
405 return gatewayPowers;
406}
407
408std::ostream&
409operator<<(std::ostream& os, const EndDeviceStatus& status)
410{
411 os << "Total packets received: " << status.m_receivedPacketList.size() << std::endl;
412
413 for (auto j = status.m_receivedPacketList.begin(); j != status.m_receivedPacketList.end(); j++)
414 {
415 EndDeviceStatus::ReceivedPacketInfo info = (*j).second;
416 EndDeviceStatus::GatewayList gatewayList = info.gwList;
417 Ptr<const Packet> pkt = (*j).first;
418 os << pkt << " " << gatewayList.size() << std::endl;
419 for (auto k = gatewayList.begin(); k != gatewayList.end(); k++)
420 {
421 EndDeviceStatus::PacketInfoPerGw infoPerGw = (*k).second;
422 os << " " << infoPerGw.gwAddress << " " << infoPerGw.rxPower << std::endl;
423 }
424 }
425
426 return os;
427}
428} // namespace lorawan
429} // namespace ns3
a polymophic address class
Definition: address.h:101
An identifier for simulation events.
Definition: event-id.h:56
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:285
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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:37
double GetReceivePower() const
Read the power this packet arrived with.
Definition: lora-tag.cc:106
uint8_t GetSpreadingFactor() const
Read which Spreading Factor this packet was transmitted with.
Definition: lora-tag.cc:94
double GetFrequency() const
Get the frequency of the packet.
Definition: lora-tag.cc:136
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:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:275
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:615
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.