A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
network-status.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 * Authors: Davide Magrin <magrinda@dei.unipd.it>
7 * Martina Capuzzo <capuzzom@dei.unipd.it>
8 */
9
10#include "network-status.h"
11
12#include "end-device-status.h"
13#include "gateway-status.h"
14#include "lora-device-address.h"
15
16#include "ns3/log.h"
17#include "ns3/net-device.h"
18#include "ns3/node-container.h"
19#include "ns3/packet.h"
20#include "ns3/pointer.h"
21
22namespace ns3
23{
24namespace lorawan
25{
26
27NS_LOG_COMPONENT_DEFINE("NetworkStatus");
28
29NS_OBJECT_ENSURE_REGISTERED(NetworkStatus);
30
31TypeId
33{
34 static TypeId tid = TypeId("ns3::NetworkStatus")
36 .AddConstructor<NetworkStatus>()
37 .SetGroupName("lorawan");
38 return tid;
39}
40
45
50
51void
53{
54 NS_LOG_FUNCTION(this << edMac);
55
56 // Check whether this device already exists in our list
57 LoraDeviceAddress edAddress = edMac->GetDeviceAddress();
58 if (m_endDeviceStatuses.find(edAddress) == m_endDeviceStatuses.end())
59 {
60 // The device doesn't exist. Create new EndDeviceStatus
61 Ptr<EndDeviceStatus> edStatus =
63
64 // Add it to the map
66 std::pair<LoraDeviceAddress, Ptr<EndDeviceStatus>>(edAddress, edStatus));
67 NS_LOG_DEBUG("Added to the list a device with address " << edAddress.Print());
68 }
69}
70
71void
73{
74 NS_LOG_FUNCTION(this);
75
76 // Check whether this device already exists in the list
77 if (m_gatewayStatuses.find(address) == m_gatewayStatuses.end())
78 {
79 // The device doesn't exist.
80
81 // Add it to the map
82 m_gatewayStatuses.insert(std::pair<Address, Ptr<GatewayStatus>>(address, gwStatus));
83 NS_LOG_DEBUG("Added to the list a gateway with address " << address);
84 }
85}
86
87void
89{
90 NS_LOG_FUNCTION(this << packet << gwAddress);
91
92 // Create a copy of the packet
93 Ptr<Packet> myPacket = packet->Copy();
94
95 // Extract the headers
96 LorawanMacHeader macHdr;
97 myPacket->RemoveHeader(macHdr);
98 LoraFrameHeader frameHdr;
99 frameHdr.SetAsUplink();
100 myPacket->RemoveHeader(frameHdr);
101
102 // Update the correct EndDeviceStatus object
103 LoraDeviceAddress edAddr = frameHdr.GetAddress();
104 NS_LOG_DEBUG("Node address: " << edAddr);
105 m_endDeviceStatuses.at(edAddr)->InsertReceivedPacket(packet, gwAddress);
106}
107
108bool
110{
111 // Throws out of range if no device is found
112 return m_endDeviceStatuses.at(deviceAddress)->NeedsReply();
113}
114
117{
118 // Get the endDeviceStatus we are interested in
119 Ptr<EndDeviceStatus> edStatus = m_endDeviceStatuses.at(deviceAddress);
120 double replyFrequency;
121 if (window == 1)
122 {
123 replyFrequency = edStatus->GetFirstReceiveWindowFrequency();
124 }
125 else if (window == 2)
126 {
127 replyFrequency = edStatus->GetSecondReceiveWindowFrequency();
128 }
129 else
130 {
131 NS_ABORT_MSG("Invalid window value");
132 }
133
134 // Get the list of gateways that this device can reach
135 // NOTE: At this point, we could also take into account the whole network to
136 // identify the best gateway according to various metrics. For now, we just
137 // ask the EndDeviceStatus to pick the best gateway for us via its method.
138 std::map<double, Address> gwAddresses = edStatus->GetPowerGatewayMap();
139
140 // By iterating on the map in reverse, we go from the 'best'
141 // gateway, i.e. the one with the highest received power, to the
142 // worst.
143 Address bestGwAddress;
144 for (auto it = gwAddresses.rbegin(); it != gwAddresses.rend(); it++)
145 {
146 bool isAvailable =
147 m_gatewayStatuses.find(it->second)->second->IsAvailableForTransmission(replyFrequency);
148 if (isAvailable)
149 {
150 bestGwAddress = it->second;
151 break;
152 }
153 }
154
155 return bestGwAddress;
156}
157
158void
160{
161 NS_LOG_FUNCTION(packet << gwAddress);
162
163 m_gatewayStatuses.find(gwAddress)->second->GetNetDevice()->Send(packet, gwAddress, 0x0800);
164}
165
168{
169 // Get the reply packet
170 Ptr<EndDeviceStatus> edStatus = m_endDeviceStatuses.find(edAddress)->second;
171 Ptr<Packet> packet = edStatus->GetCompleteReplyPacket();
172
173 // Apply the appropriate tag
174 LoraTag tag;
175 switch (windowNumber)
176 {
177 case 1:
178 tag.SetDataRate(edStatus->GetMac()->GetFirstReceiveWindowDataRate());
179 tag.SetFrequency(edStatus->GetFirstReceiveWindowFrequency());
180 break;
181 case 2:
182 tag.SetDataRate(edStatus->GetMac()->GetSecondReceiveWindowDataRate());
183 tag.SetFrequency(edStatus->GetSecondReceiveWindowFrequency());
184 break;
185 }
186
187 packet->AddPacketTag(tag);
188 return packet;
189}
190
193{
194 NS_LOG_FUNCTION(this << packet);
195
196 // Get the address
197 LorawanMacHeader mHdr;
198 LoraFrameHeader fHdr;
199 Ptr<Packet> myPacket = packet->Copy();
200 myPacket->RemoveHeader(mHdr);
201 myPacket->RemoveHeader(fHdr);
202 auto it = m_endDeviceStatuses.find(fHdr.GetAddress());
203 if (it != m_endDeviceStatuses.end())
204 {
205 return (*it).second;
206 }
207 else
208 {
209 NS_LOG_ERROR("EndDeviceStatus not found");
210 return nullptr;
211 }
212}
213
216{
217 NS_LOG_FUNCTION(this << address);
218
219 auto it = m_endDeviceStatuses.find(address);
220 if (it != m_endDeviceStatuses.end())
221 {
222 return (*it).second;
223 }
224 else
225 {
226 NS_LOG_ERROR("EndDeviceStatus not found");
227 return nullptr;
228 }
229}
230
231int
233{
234 NS_LOG_FUNCTION(this);
235
236 return m_endDeviceStatuses.size();
237}
238} // namespace lorawan
239} // namespace ns3
a polymophic address class
Definition address.h:90
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
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 device address of a LoraWAN end device.
std::string Print() const
Print the address bit-by-bit to a human-readable string.
This class represents the Frame header (FHDR) used in a LoraWAN network.
void SetAsUplink()
State that this is an uplink message.
LoraDeviceAddress GetAddress() const
Get this header's device address value.
Tag used to save various data about a packet, like its Spreading Factor and data about interference.
Definition lora-tag.h:26
void SetDataRate(uint8_t dataRate)
Set the data rate for this packet.
Definition lora-tag.cc:137
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition lora-tag.cc:119
This class represents the Mac header of a LoRaWAN packet.
~NetworkStatus() override
Destructor.
Ptr< EndDeviceStatus > GetEndDeviceStatus(Ptr< const Packet > packet)
Get the EndDeviceStatus of the device that sent a packet.
void OnReceivedPacket(Ptr< const Packet > packet, const Address &gwaddress)
Update network status on a received packet.
NetworkStatus()
Default constructor.
bool NeedsReply(LoraDeviceAddress deviceAddress)
Return whether the specified device needs a reply.
void AddNode(Ptr< ClassAEndDeviceLorawanMac > edMac)
Add a device to the ones that are tracked by this NetworkStatus object.
int CountEndDevices()
Return the number of end devices currently managed by the server.
std::map< LoraDeviceAddress, Ptr< EndDeviceStatus > > m_endDeviceStatuses
Map tracking the state of devices connected to this network server.
void SendThroughGateway(Ptr< Packet > packet, Address gwAddress)
Send a packet through a gateway.
std::map< Address, Ptr< GatewayStatus > > m_gatewayStatuses
Map tracking the state of gateways connected to this network server.
void AddGateway(Address &address, Ptr< GatewayStatus > gwStatus)
Add a new gateway to the list of gateways connected to the network.
static TypeId GetTypeId()
Register this type.
Ptr< Packet > GetReplyForDevice(LoraDeviceAddress edAddress, int windowNumber)
Get the reply packet prepared for a reception window of a device.
Address GetBestGatewayForDevice(LoraDeviceAddress deviceAddress, int window)
Return whether we have a gateway that is available to send a reply to the specified device.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#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 ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580