Loading...
Searching...
No Matches
lora-network-scheduler.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 * Author: Davide Magrin <magrinda@dei.unipd.it>
19 *
20 * Modified by: Bastien Tauran <bastien.tauran@viveris.fr>
21 */
22
24
25#include <stdint.h>
26
27NS_LOG_COMPONENT_DEFINE("LoraNetworkScheduler");
28
29namespace ns3
30{
31
32NS_OBJECT_ENSURE_REGISTERED(LoraNetworkScheduler);
33
34TypeId
36{
37 static TypeId tid =
38 TypeId("ns3::LoraNetworkScheduler")
39 .SetParent<Object>()
40 .AddAttribute("FirstWindowAnswerDelay",
41 "Delay to wait between end of reception of paquet and sending of anwser, "
42 "to be in first window opportunity",
43 TimeValue(Seconds(1)),
45 MakeTimeChecker())
46 .AddAttribute("SecondWindowAnswerDelay",
47 "Delay to wait between end of reception of paquet and sending of anwser, "
48 "to be in second window opportunity",
49 TimeValue(Seconds(2)),
51 MakeTimeChecker())
52 .AddTraceSource("ReceiveWindowOpened",
53 "Trace source that is fired when a receive window opportunity happens.",
54 MakeTraceSourceAccessor(&LoraNetworkScheduler::m_receiveWindowOpened),
55 "ns3::Packet::TracedCallback")
56 .AddConstructor<LoraNetworkScheduler>();
57 return tid;
58}
59
63
64LoraNetworkScheduler::LoraNetworkScheduler(Ptr<LoraNetworkStatus> status,
65 Ptr<LoraNetworkController> controller)
66 : m_status(status),
67 m_controller(controller),
68 m_firstWindowAnswerDelay(Seconds(1)),
70{
71 NS_LOG_FUNCTION(this << status << controller);
72}
73
74void
76{
77 NS_LOG_FUNCTION(this);
78
79 Object::NotifyConstructionCompleted();
80
82 "First window answer delay must be lower than second window answer delay");
83}
84
88
89void
91{
92 NS_LOG_FUNCTION(packet);
93
94 // Get the current packet's frame counter
95 Ptr<Packet> packetCopy = packet->Copy();
96 LorawanMacHeader receivedMacHdr;
97 packetCopy->RemoveHeader(receivedMacHdr);
98 LoraFrameHeader receivedFrameHdr;
99 receivedFrameHdr.SetAsUplink();
100 packetCopy->RemoveHeader(receivedFrameHdr);
101
102 // Need to decide whether to schedule a receive window
103 if (!m_status->GetEndDeviceStatus(packet)->HasReceiveWindowOpportunityScheduled())
104 {
105 // Extract the address
106 LoraDeviceAddress deviceAddress = receivedFrameHdr.GetAddress();
107
108 // Schedule OnReceiveWindowOpportunity event
109 m_status->GetEndDeviceStatus(packet)->SetReceiveWindowOpportunity(
110 Simulator::Schedule(m_firstWindowAnswerDelay,
112 this,
113 deviceAddress,
114 1));
115 }
116}
117
118void
120{
121 NS_LOG_FUNCTION(deviceAddress);
122
123 NS_LOG_DEBUG("Opening receive window number " << window << " for device " << deviceAddress);
124
125 // Check whether we can send a reply to the device, again by using
126 // NetworkStatus
127 Address gwAddress = m_status->GetBestGatewayForDevice(deviceAddress, window);
128
129 if (gwAddress == Address() && window == 1)
130 {
131 NS_LOG_DEBUG("No suitable gateway found for first window.");
132
133 // No suitable GW was found, but there's still hope to find one for the
134 // second window.
135 // Schedule another OnReceiveWindowOpportunity event
136 m_status->GetEndDeviceStatus(deviceAddress)
137 ->SetReceiveWindowOpportunity(
138 Simulator::Schedule(m_secondWindowAnswerDelay,
140 this,
141 deviceAddress,
142 2));
143 }
144 else if (gwAddress == Address() && window == 2)
145 {
146 // No suitable GW was found and this was our last opportunity
147 // Simply give up.
148 NS_LOG_DEBUG("Giving up on reply: no suitable gateway was found "
149 << "on the second receive window");
150
151 // Reset the reply
152 // XXX Should we reset it here or keep it for the next opportunity?
153 m_status->GetEndDeviceStatus(deviceAddress)->RemoveReceiveWindowOpportunity();
154 m_status->GetEndDeviceStatus(deviceAddress)->InitializeReply();
155 }
156 else
157 {
158 // A gateway was found
159
160 NS_LOG_DEBUG("Found available gateway with address: " << gwAddress);
161
162 m_controller->BeforeSendingReply(m_status->GetEndDeviceStatus(deviceAddress));
163
164 // Check whether this device needs a response by querying m_status
165 bool needsReply = m_status->NeedsReply(deviceAddress);
166
167 if (needsReply)
168 {
169 NS_LOG_INFO("A reply is needed");
170
171 // Send the reply through that gateway
172 m_status->SendThroughGateway(m_status->GetReplyForDevice(deviceAddress, window),
173 gwAddress);
174
175 // Reset the reply
176 m_status->GetEndDeviceStatus(deviceAddress)->RemoveReceiveWindowOpportunity();
177 m_status->GetEndDeviceStatus(deviceAddress)->InitializeReply();
178 }
179 }
180}
181} // namespace ns3
This class represents the device address of a LoraWAN End Device.
This class represents the Frame header (FHDR) used in a LoraWAN network.
void SetAsUplink(void)
State that this is an uplink message.
LoraDeviceAddress GetAddress(void) const
Get this header's device address value.
Time m_secondWindowAnswerDelay
Delay to wait between end of reception of paquet and sending of anwser, to be in second window opport...
Ptr< LoraNetworkStatus > m_status
void OnReceivedPacket(Ptr< const Packet > packet)
Method called by NetworkServer to inform the Scheduler of a newly arrived uplink packet.
Time m_firstWindowAnswerDelay
Delay to wait between end of reception of paquet and sending of anwser, to be in first window opportu...
void OnReceiveWindowOpportunity(LoraDeviceAddress deviceAddress, int window)
Method that is scheduled after packet arrivals in order to act on receive windows 1 and 2 seconds lat...
Ptr< LoraNetworkController > m_controller
TracedCallback< Ptr< const Packet > > m_receiveWindowOpened
virtual void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
This class represents the Mac header of a LoRaWAN packet.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.