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 * 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: Davide Magrin <magrinda@dei.unipd.it>
18 * Martina Capuzzo <capuzzom@dei.unipd.it>
19 */
20
21#include "network-status.h"
22
23#include "end-device-status.h"
24#include "gateway-status.h"
25#include "lora-device-address.h"
26
27#include "ns3/log.h"
28#include "ns3/net-device.h"
29#include "ns3/node-container.h"
30#include "ns3/packet.h"
31#include "ns3/pointer.h"
32
33namespace ns3
34{
35namespace lorawan
36{
37
38NS_LOG_COMPONENT_DEFINE("NetworkStatus");
39
40NS_OBJECT_ENSURE_REGISTERED(NetworkStatus);
41
42TypeId
44{
45 static TypeId tid = TypeId("ns3::NetworkStatus")
47 .AddConstructor<NetworkStatus>()
48 .SetGroupName("lorawan");
49 return tid;
50}
51
53{
55}
56
58{
60}
61
62void
64{
65 NS_LOG_FUNCTION(this << edMac);
66
67 // Check whether this device already exists in our list
68 LoraDeviceAddress edAddress = edMac->GetDeviceAddress();
69 if (m_endDeviceStatuses.find(edAddress) == m_endDeviceStatuses.end())
70 {
71 // The device doesn't exist. Create new EndDeviceStatus
72 Ptr<EndDeviceStatus> edStatus =
73 CreateObject<EndDeviceStatus>(edAddress, edMac->GetObject<ClassAEndDeviceLorawanMac>());
74
75 // Add it to the map
77 std::pair<LoraDeviceAddress, Ptr<EndDeviceStatus>>(edAddress, edStatus));
78 NS_LOG_DEBUG("Added to the list a device with address " << edAddress.Print());
79 }
80}
81
82void
84{
85 NS_LOG_FUNCTION(this);
86
87 // Check whether this device already exists in the list
88 if (m_gatewayStatuses.find(address) == m_gatewayStatuses.end())
89 {
90 // The device doesn't exist.
91
92 // Add it to the map
93 m_gatewayStatuses.insert(std::pair<Address, Ptr<GatewayStatus>>(address, gwStatus));
94 NS_LOG_DEBUG("Added to the list a gateway with address " << address);
95 }
96}
97
98void
100{
101 NS_LOG_FUNCTION(this << packet << gwAddress);
102
103 // Create a copy of the packet
104 Ptr<Packet> myPacket = packet->Copy();
105
106 // Extract the headers
107 LorawanMacHeader macHdr;
108 myPacket->RemoveHeader(macHdr);
109 LoraFrameHeader frameHdr;
110 frameHdr.SetAsUplink();
111 myPacket->RemoveHeader(frameHdr);
112
113 // Update the correct EndDeviceStatus object
114 LoraDeviceAddress edAddr = frameHdr.GetAddress();
115 NS_LOG_DEBUG("Node address: " << edAddr);
116 m_endDeviceStatuses.at(edAddr)->InsertReceivedPacket(packet, gwAddress);
117}
118
119bool
121{
122 // Throws out of range if no device is found
123 return m_endDeviceStatuses.at(deviceAddress)->NeedsReply();
124}
125
128{
129 // Get the endDeviceStatus we are interested in
130 Ptr<EndDeviceStatus> edStatus = m_endDeviceStatuses.at(deviceAddress);
131 double replyFrequency;
132 if (window == 1)
133 {
134 replyFrequency = edStatus->GetFirstReceiveWindowFrequency();
135 }
136 else if (window == 2)
137 {
138 replyFrequency = edStatus->GetSecondReceiveWindowFrequency();
139 }
140 else
141 {
142 NS_ABORT_MSG("Invalid window value");
143 }
144
145 // Get the list of gateways that this device can reach
146 // NOTE: At this point, we could also take into account the whole network to
147 // identify the best gateway according to various metrics. For now, we just
148 // ask the EndDeviceStatus to pick the best gateway for us via its method.
149 std::map<double, Address> gwAddresses = edStatus->GetPowerGatewayMap();
150
151 // By iterating on the map in reverse, we go from the 'best'
152 // gateway, i.e. the one with the highest received power, to the
153 // worst.
154 Address bestGwAddress;
155 for (auto it = gwAddresses.rbegin(); it != gwAddresses.rend(); it++)
156 {
157 bool isAvailable =
158 m_gatewayStatuses.find(it->second)->second->IsAvailableForTransmission(replyFrequency);
159 if (isAvailable)
160 {
161 bestGwAddress = it->second;
162 break;
163 }
164 }
165
166 return bestGwAddress;
167}
168
169void
171{
172 NS_LOG_FUNCTION(packet << gwAddress);
173
174 m_gatewayStatuses.find(gwAddress)->second->GetNetDevice()->Send(packet, gwAddress, 0x0800);
175}
176
179{
180 // Get the reply packet
181 Ptr<EndDeviceStatus> edStatus = m_endDeviceStatuses.find(edAddress)->second;
182 Ptr<Packet> packet = edStatus->GetCompleteReplyPacket();
183
184 // Apply the appropriate tag
185 LoraTag tag;
186 switch (windowNumber)
187 {
188 case 1:
189 tag.SetDataRate(edStatus->GetMac()->GetFirstReceiveWindowDataRate());
190 tag.SetFrequency(edStatus->GetFirstReceiveWindowFrequency());
191 break;
192 case 2:
193 tag.SetDataRate(edStatus->GetMac()->GetSecondReceiveWindowDataRate());
194 tag.SetFrequency(edStatus->GetSecondReceiveWindowFrequency());
195 break;
196 }
197
198 packet->AddPacketTag(tag);
199 return packet;
200}
201
204{
205 NS_LOG_FUNCTION(this << packet);
206
207 // Get the address
208 LorawanMacHeader mHdr;
209 LoraFrameHeader fHdr;
210 Ptr<Packet> myPacket = packet->Copy();
211 myPacket->RemoveHeader(mHdr);
212 myPacket->RemoveHeader(fHdr);
213 auto it = m_endDeviceStatuses.find(fHdr.GetAddress());
214 if (it != m_endDeviceStatuses.end())
215 {
216 return (*it).second;
217 }
218 else
219 {
220 NS_LOG_ERROR("EndDeviceStatus not found");
221 return nullptr;
222 }
223}
224
227{
228 NS_LOG_FUNCTION(this << address);
229
230 auto it = m_endDeviceStatuses.find(address);
231 if (it != m_endDeviceStatuses.end())
232 {
233 return (*it).second;
234 }
235 else
236 {
237 NS_LOG_ERROR("EndDeviceStatus not found");
238 return nullptr;
239 }
240}
241
242int
244{
245 NS_LOG_FUNCTION(this);
246
247 return m_endDeviceStatuses.size();
248}
249} // namespace lorawan
250} // namespace ns3
a polymophic address class
Definition: address.h:101
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Class representing the MAC layer of a Class A LoRaWAN device.
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:37
void SetDataRate(uint8_t dataRate)
Set the data rate for this packet.
Definition: lora-tag.cc:148
void SetFrequency(double frequency)
Set the frequency of the packet.
Definition: lora-tag.cc:130
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:49
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#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_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.