A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
network-controller-components.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 * Author: Davide Magrin <magrinda@dei.unipd.it>
7 */
8
10
11#include "network-status.h"
12
13namespace ns3
14{
15namespace lorawan
16{
17
18NS_LOG_COMPONENT_DEFINE("NetworkControllerComponent");
19
21
22TypeId
24{
25 static TypeId tid =
26 TypeId("ns3::NetworkControllerComponent").SetParent<Object>().SetGroupName("lorawan");
27 return tid;
28}
29
33
37
38////////////////////////////////
39// ConfirmedMessagesComponent //
40////////////////////////////////
43{
44 static TypeId tid = TypeId("ns3::ConfirmedMessagesComponent")
46 .AddConstructor<ConfirmedMessagesComponent>()
47 .SetGroupName("lorawan");
48 return tid;
49}
50
54
58
59void
62 Ptr<NetworkStatus> networkStatus)
63{
64 NS_LOG_FUNCTION(this->GetTypeId() << packet << networkStatus);
65
66 // Check whether the received packet requires an acknowledgment.
68 LoraFrameHeader fHdr;
69 fHdr.SetAsUplink();
70 Ptr<Packet> myPacket = packet->Copy();
71 myPacket->RemoveHeader(mHdr);
72 myPacket->RemoveHeader(fHdr);
73
74 NS_LOG_INFO("Received packet Mac Header: " << mHdr);
75 NS_LOG_INFO("Received packet Frame Header: " << fHdr);
76
78 {
79 NS_LOG_INFO("Packet requires confirmation");
80
81 // Set up the ACK bit on the reply
82 status->m_reply.frameHeader.SetAsDownlink();
83 status->m_reply.frameHeader.SetAck(true);
84 status->m_reply.frameHeader.SetAddress(fHdr.GetAddress());
85 status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN);
86 status->m_reply.needsReply = true;
87
88 // Note that the acknowledgment procedure dies here: "Acknowledgments
89 // are only snt in response to the latest message received and are never
90 // retransmitted". We interpret this to mean that only the current
91 // reception window can be used, and that the Ack field should be
92 // emptied in case transmission cannot be performed in the current
93 // window. Because of this, in this component's OnFailedReply method we
94 // void the ack bits.
95 }
96 else if (fHdr.GetAdrAckReq())
97 {
98 NS_LOG_INFO("Packet has ADRACKReq bit set");
99
100 // Configure reply
101 status->m_reply.frameHeader.SetAsDownlink();
102 status->m_reply.frameHeader.SetAck(false);
103 status->m_reply.frameHeader.SetAddress(fHdr.GetAddress());
104 status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN);
105 status->m_reply.needsReply = true;
106 }
107}
108
109void
111 Ptr<NetworkStatus> networkStatus)
112{
113 NS_LOG_FUNCTION(this << status << networkStatus);
114 // Nothing to do in this case
115}
116
117void
119 Ptr<NetworkStatus> networkStatus)
120{
121 NS_LOG_FUNCTION(this << networkStatus);
122
123 // Empty the Ack bit.
124 status->m_reply.frameHeader.SetAck(false);
125}
126
127////////////////////////
128// LinkCheckComponent //
129////////////////////////
130TypeId
132{
133 static TypeId tid = TypeId("ns3::LinkCheckComponent")
135 .AddConstructor<LinkCheckComponent>()
136 .SetGroupName("lorawan");
137 return tid;
138}
139
143
147
148void
151 Ptr<NetworkStatus> networkStatus)
152{
153 NS_LOG_FUNCTION(this->GetTypeId() << packet << networkStatus);
154
155 // We will only act just before reply, when all Gateways will have received
156 // the packet.
157}
158
159void
161 Ptr<NetworkStatus> networkStatus)
162{
163 NS_LOG_FUNCTION(this << status << networkStatus);
164
165 Ptr<Packet> myPacket = status->GetLastPacketReceivedFromDevice()->Copy();
166 LorawanMacHeader mHdr;
167 LoraFrameHeader fHdr;
168 fHdr.SetAsUplink();
169 myPacket->RemoveHeader(mHdr);
170 myPacket->RemoveHeader(fHdr);
171
173
174 // GetMacCommand returns 0 if no command is found
175 if (command)
176 {
177 status->m_reply.needsReply = true;
178
179 auto info = status->GetLastReceivedPacketInfo();
180
181 // Adapted from: github.com/chirpstack/chirpstack v4.9.0
182
183 // Get the best demodulation margin of the most recent LinkCheckReq command
184 double maxRssi = -1e3;
185 for (const auto& [_, gwRxData] : info.gwList)
186 {
187 if (gwRxData.rxPower > maxRssi)
188 {
189 maxRssi = gwRxData.rxPower;
190 }
191 }
192 /// @see ns3::lorawan::AdrComponent::RxPowerToSNR
193 double maxSnr = maxRssi + 174 - 10 * log10(125000) - 6;
194 /// @todo make this a global PHY constant, manage unknown sf values
195 double requiredSnr[] = {-20.0, -17.5, -15.0, -12.5, -10.0, -7.5, -5};
196 double diff = maxSnr - requiredSnr[12 - info.sf];
197 uint8_t margin = (diff < 0) ? 0 : (diff > 254) ? 254 : diff;
198
199 // Get the number of gateways that received the most recent LinkCheckReq command
200 uint8_t gwCount = info.gwList.size();
201
202 auto replyCommand = Create<LinkCheckAns>(margin, gwCount);
203 status->m_reply.frameHeader.SetAsDownlink();
204 status->m_reply.frameHeader.AddCommand(replyCommand);
205 status->m_reply.macHeader.SetMType(LorawanMacHeader::UNCONFIRMED_DATA_DOWN);
206 }
207 else
208 {
209 // Do nothing
210 }
211}
212
213void
215{
216 NS_LOG_FUNCTION(this->GetTypeId() << networkStatus);
217}
218
219} // namespace lorawan
220} // namespace ns3
Object()
Caller graph was not generated because of its size.
Definition object.cc:93
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
void BeforeSendingReply(Ptr< EndDeviceStatus > status, Ptr< NetworkStatus > networkStatus) override
Function called as a downlink reply is about to leave the NetworkServer application.
void OnFailedReply(Ptr< EndDeviceStatus > status, Ptr< NetworkStatus > networkStatus) override
Method that is called when a packet cannot be sent in the downlink.
void OnReceivedPacket(Ptr< const Packet > packet, Ptr< EndDeviceStatus > status, Ptr< NetworkStatus > networkStatus) override
This method checks whether the received packet requires an acknowledgment and sets up the appropriate...
This class represents the Frame header (FHDR) used in a LoraWAN network.
Ptr< T > GetMacCommand()
Return a pointer to the first MacCommand of type T, or 0 if no such MacCommand exists in this header.
bool GetAdrAckReq() const
Get the value of the ADRACKReq bit field.
void SetAsUplink()
State that this is an uplink message.
LoraDeviceAddress GetAddress() const
Get this header's device address value.
This class represents the Mac header of a LoRaWAN packet.
uint8_t GetMType() const
Get the message type from the header.
Generic class describing a component of the NetworkController.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#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:267
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
Every class exported by the ns3 library is enclosed in the ns3 namespace.