Loading...
Searching...
No Matches
lora-end-device-status.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2017 University of Padova
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Martina Capuzzo <capuzzom@dei.unipd.it>
19 * Davide Magrin <magrinda@dei.unipd.it>
20 *
21 * Modified by: Bastien Tauran <bastien.tauran@viveris.fr>
22 */
23
25
26#include "lora-beam-tag.h"
27#include "lora-frame-header.h"
28#include "lora-tag.h"
29#include "lorawan-mac-header.h"
31#include "satellite-topology.h"
32
33#include "ns3/command-line.h"
34#include "ns3/log.h"
35#include "ns3/packet.h"
36#include "ns3/pointer.h"
37#include "ns3/simulator.h"
38#include "ns3/singleton.h"
39
40#include <algorithm>
41#include <iostream>
42#include <map>
43#include <ostream>
44#include <utility>
45
46namespace ns3
47{
48
49NS_LOG_COMPONENT_DEFINE("LoraEndDeviceStatus");
50
51TypeId
53{
54 static TypeId tid = TypeId("ns3::LoraEndDeviceStatus")
55 .SetParent<Object>()
56 .AddConstructor<LoraEndDeviceStatus>();
57 return tid;
58}
59
61 Ptr<LorawanMacEndDeviceClassA> endDeviceMac)
63 m_endDeviceAddress(endDeviceAddress),
64 m_utAddress(endDeviceMac->GetAddress()),
66 m_mac(endDeviceMac)
67{
68 NS_LOG_FUNCTION(endDeviceAddress);
69}
70
72{
73 NS_LOG_FUNCTION_NOARGS();
74
75 // Initialize data structure
78}
79
81{
82 NS_LOG_FUNCTION_NOARGS();
83}
84
86// Getters //
88
89uint8_t
91{
92 NS_LOG_FUNCTION_NOARGS();
93 return m_modcod;
94}
95
96uint8_t
98{
99 NS_LOG_FUNCTION_NOARGS();
100 return m_beamId;
101}
102
103uint8_t
110
111double
113{
114 NS_LOG_FUNCTION_NOARGS();
115
117}
118
119uint8_t
121{
122 NS_LOG_FUNCTION_NOARGS();
123
125}
126
127double
133
134Ptr<Packet>
136{
137 NS_LOG_FUNCTION_NOARGS();
138
139 // Start from reply payload
140 Ptr<Packet> replyPacket;
141 if (m_reply.payload) // If it has APP data to send
142 {
143 NS_LOG_DEBUG("Crafting reply packet from existing payload");
144 replyPacket = m_reply.payload->Copy();
145 }
146 else // If no APP data needs to be sent, use an empty payload
147 {
148 NS_LOG_DEBUG("Crafting reply packet using an empty payload");
149 replyPacket = Create<Packet>(0);
150 }
151
152 // Add headers
153 m_reply.frameHeader.SetAddress(m_endDeviceAddress);
154 Ptr<Packet> lastPacket = GetLastPacketReceivedFromDevice()->Copy();
156 LorawanMacHeader mHdr;
157 LoraFrameHeader fHdr;
158 fHdr.SetAsUplink();
159 lastPacket->RemoveHeader(mHdr);
160 lastPacket->RemoveHeader(fHdr);
161 m_reply.frameHeader.SetFCnt(fHdr.GetFCnt());
163 replyPacket->AddHeader(m_reply.frameHeader);
164 replyPacket->AddHeader(m_reply.macHeader);
165
166 if (Singleton<SatTopology>::Get()->GetForwardLinkRegenerationMode() ==
168 {
169 SatGroundStationAddressTag groundStationAddressTag =
170 SatGroundStationAddressTag(Mac48Address::ConvertFrom(m_utAddress));
171 replyPacket->AddPacketTag(groundStationAddressTag);
172 }
173
174 NS_LOG_DEBUG("Added MAC header" << m_reply.macHeader);
175 NS_LOG_DEBUG("Added frame header" << m_reply.frameHeader);
176
177 return replyPacket;
178}
179
180bool
182{
183 NS_LOG_FUNCTION_NOARGS();
184
185 return m_reply.needsReply;
186}
187
190{
191 NS_LOG_FUNCTION_NOARGS();
192 return m_reply.macHeader;
193}
194
197{
198 NS_LOG_FUNCTION_NOARGS();
199 return m_reply.frameHeader;
200}
201
202Ptr<Packet>
204{
205 NS_LOG_FUNCTION_NOARGS();
206 return m_reply.payload->Copy();
207}
208
209Ptr<LorawanMacEndDeviceClassA>
211{
212 return m_mac;
213}
214
217{
218 NS_LOG_FUNCTION_NOARGS();
220}
221
222void
224{
225 NS_LOG_FUNCTION(this << modcod);
226 m_modcod = modcod;
227}
228
229void
231{
232 NS_LOG_FUNCTION(this << beamId);
233
234 m_beamId = beamId;
235}
236
237void
239{
240 NS_LOG_FUNCTION(this << sf);
242}
243
244void
246{
247 NS_LOG_FUNCTION(this << frequency);
249}
250
251void
253{
254 NS_LOG_FUNCTION(this << offset);
256}
257
258void
260{
261 NS_LOG_FUNCTION(this << frequency);
263}
264
265void
267{
268 NS_LOG_FUNCTION_NOARGS();
269 m_reply.macHeader = macHeader;
270}
271
272void
274{
275 NS_LOG_FUNCTION_NOARGS();
276 m_reply.frameHeader = frameHeader;
277}
278
279void
281{
282 NS_LOG_FUNCTION(this << replyPayload);
283 m_reply.payload = replyPayload;
284}
285
287// Other methods //
289
290void
291LoraEndDeviceStatus::InsertReceivedPacket(Ptr<const Packet> receivedPacket,
292 const Address& gwAddress)
293{
294 NS_LOG_FUNCTION(this << receivedPacket << gwAddress);
295
296 // Create a copy of the packet
297 Ptr<Packet> myPacket = receivedPacket->Copy();
298
299 // Update current parameters
300 LoraBeamTag beamTag;
301 myPacket->RemovePacketTag(beamTag);
302 SetBeamId(beamTag.GetBeamId());
303
304 // Extract the headers
305 LorawanMacHeader macHdr;
306 myPacket->RemoveHeader(macHdr);
307
308 LoraFrameHeader frameHdr;
309 frameHdr.SetAsUplink();
310 myPacket->RemoveHeader(frameHdr);
311
312 // Update current parameters
313 LoraTag tag;
314 myPacket->RemovePacketTag(tag);
317 SetModcod(tag.GetModcod());
318
319 // Update Information on the received packet
321 info.sf = tag.GetSpreadingFactor();
322 info.frequency = tag.GetFrequency();
323 info.packet = receivedPacket;
324
325 double rcvPower = tag.GetReceivePower();
326
327 // Perform insertion in list, also checking that the packet isn't already in
328 // the list (it could have been received by another GW already)
329
330 // Start searching from the end
331 auto it = m_receivedPacketList.rbegin();
332 for (; it != m_receivedPacketList.rend(); it++)
333 {
334 // Get the frame counter of the current packet to compare it with the
335 // newly received one
336 Ptr<Packet> packetCopy = ((*it).first)->Copy();
337 LorawanMacHeader currentMacHdr;
338 packetCopy->RemoveHeader(currentMacHdr);
339 LoraFrameHeader currentFrameHdr;
340 frameHdr.SetAsUplink();
341 packetCopy->RemoveHeader(currentFrameHdr);
342
343 NS_LOG_DEBUG("Received packet's frame counter: " << unsigned(frameHdr.GetFCnt())
344 << "\nCurrent packet's frame counter: "
345 << unsigned(currentFrameHdr.GetFCnt()));
346
347 if (frameHdr.GetFCnt() == currentFrameHdr.GetFCnt())
348 {
349 NS_LOG_INFO("Packet was already received by another gateway");
350
351 // This packet had already been received from another gateway:
352 // add this gateway's reception information.
353 GatewayList& gwList = it->second.gwList;
354
355 PacketInfoPerGw gwInfo;
356 gwInfo.receivedTime = Simulator::Now();
357 gwInfo.rxPower = rcvPower;
358 gwInfo.gwAddress = gwAddress;
359 gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
360
361 NS_LOG_DEBUG("Size of gateway list: " << gwList.size());
362
363 break; // Exit from the cycle
364 }
365 }
366 if (it == m_receivedPacketList.rend())
367 {
368 NS_LOG_INFO("Packet was received for the first time");
369 PacketInfoPerGw gwInfo;
370 gwInfo.receivedTime = Simulator::Now();
371 gwInfo.rxPower = rcvPower;
372 gwInfo.gwAddress = gwAddress;
373 info.gwList.insert(std::pair<Address, PacketInfoPerGw>(gwAddress, gwInfo));
374 m_receivedPacketList.push_back(
375 std::pair<Ptr<const Packet>, ReceivedPacketInfo>(receivedPacket, info));
376 }
377 NS_LOG_DEBUG(*this);
378}
379
382{
383 NS_LOG_FUNCTION_NOARGS();
384 auto it = m_receivedPacketList.rbegin();
385 if (it != m_receivedPacketList.rend())
386 {
387 return it->second;
388 }
389 else
390 {
392 }
393}
394
395Ptr<const Packet>
397{
398 NS_LOG_FUNCTION_NOARGS();
399 auto it = m_receivedPacketList.rbegin();
400 if (it != m_receivedPacketList.rend())
401 {
402 return it->first;
403 }
404 else
405 {
406 return 0;
407 }
408}
409
410void
412{
413 NS_LOG_FUNCTION_NOARGS();
414 m_reply = Reply();
415 m_reply.needsReply = false;
416}
417
418void
419LoraEndDeviceStatus::AddMACCommand(Ptr<LorawanMacCommand> macCommand)
420{
421 m_reply.frameHeader.AddCommand(macCommand);
422}
423
424bool
429
430void
435
436void
441
442std::map<double, Address>
444{
445 // Create a map of the gateways
446 // Key: received power
447 // Value: address of the corresponding gateway
448 ReceivedPacketInfo info = m_receivedPacketList.back().second;
449 GatewayList gwList = info.gwList;
450
451 std::map<double, Address> gatewayPowers;
452
453 for (auto it = gwList.begin(); it != gwList.end(); it++)
454 {
455 Address currentGwAddress = (*it).first;
456 double currentRxPower = (*it).second.rxPower;
457 gatewayPowers.insert(std::pair<double, Address>(currentRxPower, currentGwAddress));
458 }
459
460 return gatewayPowers;
461}
462
463std::ostream&
464operator<<(std::ostream& os, const LoraEndDeviceStatus& status)
465{
466 os << "Total packets received: " << status.m_receivedPacketList.size() << std::endl;
467
468 for (auto j = status.m_receivedPacketList.begin(); j != status.m_receivedPacketList.end(); j++)
469 {
471 LoraEndDeviceStatus::GatewayList gatewayList = info.gwList;
472 Ptr<const Packet> pkt = (*j).first;
473 os << pkt << " " << gatewayList.size() << std::endl;
474 for (LoraEndDeviceStatus::GatewayList::iterator k = gatewayList.begin();
475 k != gatewayList.end();
476 k++)
477 {
478 LoraEndDeviceStatus::PacketInfoPerGw infoPerGw = (*k).second;
479 os << " " << infoPerGw.gwAddress << " " << infoPerGw.rxPower << std::endl;
480 }
481 }
482
483 return os;
484}
485} // namespace ns3
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
uint8_t GetBeamId() const
Read which beam ID this packet was transmitted with.
This class represents the device address of a LoraWAN End Device.
uint8_t GetBeamId(void)
Get the beam ID this device is using.
double GetFirstReceiveWindowFrequency(void)
Get the first window frequency of this device.
ReceivedPacketList GetReceivedPacketList(void)
Get the received packet list.
void AddMACCommand(Ptr< LorawanMacCommand > macCommand)
Add MAC command to the list.
Ptr< Packet > GetReplyPayload(void)
Get the data of the reply packet.
void SetSecondReceiveWindowFrequency(double frequency)
Set the second window frequency of this device.
void SetSecondReceiveWindowOffset(uint8_t offset)
Set 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.
void SetBeamId(uint8_t beamId)
Set the beam ID this device is using.
uint8_t GetFirstReceiveWindowSpreadingFactor(void)
Get the spreading factor this device is using in the first receive window.
LorawanMacHeader GetReplyMacHeader(void)
Get the reply packet mac header.
std::list< std::pair< Ptr< const Packet >, ReceivedPacketInfo > > ReceivedPacketList
void SetReplyMacHeader(LorawanMacHeader macHeader)
Set the reply packet mac header.
bool NeedsReply(void)
Whether the end device needs a reply.
LoraEndDeviceStatus::ReceivedPacketInfo GetLastReceivedPacketInfo(void)
Return the information about the last packet that was received from the device.
uint8_t GetModcod(void)
Get the modcod this device is using.
Ptr< Packet > GetCompleteReplyPacket(void)
Get the reply packet.
void SetReplyPayload(Ptr< Packet > replyPayload)
Set the packet reply payload.
void SetReplyFrameHeader(LoraFrameHeader frameHeader)
Set the reply packet frame header.
std::map< Address, PacketInfoPerGw > GatewayList
void InitializeReply(void)
Initialize reply.
Ptr< LorawanMacEndDeviceClassA > m_mac
Pointer to the MAC layer of this device.
double GetSecondReceiveWindowFrequency(void)
Return the second window frequency of this device.
Ptr< const Packet > GetLastPacketReceivedFromDevice(void)
Return the last packet that was received from this device.
uint8_t GetSecondReceiveWindowOffset(void)
Get the offset of spreading factor this device is using in the second receive window with respect to ...
void SetModcod(uint8_t modcod)
Set the modcod this device is using.
void InsertReceivedPacket(Ptr< const Packet > receivedPacket, const Address &gwAddress)
Insert a received packet in the packet list.
bool HasReceiveWindowOpportunityScheduled()
Returns whether we already decided we will schedule a transmission to this ED.
LoraFrameHeader GetReplyFrameHeader(void)
Get the reply packet frame header.
ReceivedPacketList m_receivedPacketList
void SetFirstReceiveWindowFrequency(double frequency)
Set the first window frequency of this device.
void SetReceiveWindowOpportunity(EventId event)
std::map< double, Address > GetPowerGatewayMap(void)
Return an ordered list of the best gateways.
Ptr< LorawanMacEndDeviceClassA > GetMac(void)
This class represents the Frame header (FHDR) used in a LoraWAN network.
void SetAsUplink(void)
State that this is an uplink message.
uint16_t GetFCnt(void) const
Get the FCnt value.
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:41
double GetFrequency(void)
Get the frequency of the packet.
Definition lora-tag.cc:142
uint8_t GetSpreadingFactor() const
Read which Spreading Factor this packet was transmitted with.
Definition lora-tag.cc:100
uint8_t GetModcod(void)
Get the modcod for this packet.
Definition lora-tag.cc:160
double GetReceivePower() const
Read the power this packet arrived with.
Definition lora-tag.cc:112
This class represents the Mac header of a LoRaWAN packet.
Tag to store ground station destination address.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
std::ostream & operator<<(std::ostream &os, const GeoCoordinate &coordinate)
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.
Ptr< const Packet > packet
The received packet.
Structure representing the reply that the network server will send this device at the first opportuni...