Loading...
Searching...
No Matches
lora-logical-channel-helper.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 "ns3/log.h"
26#include "ns3/simulator.h"
27
28#include <algorithm>
29#include <iterator>
30#include <list>
31#include <vector>
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("LoraLogicalChannelHelper");
37
38NS_OBJECT_ENSURE_REGISTERED(LoraLogicalChannelHelper);
39
40TypeId
42{
43 static TypeId tid = TypeId("ns3::LoraLogicalChannelHelper").SetParent<Object>();
44 return tid;
45}
46
53
55{
56 NS_LOG_FUNCTION(this);
57}
58
59std::vector<Ptr<LoraLogicalChannel>>
61{
62 NS_LOG_FUNCTION(this);
63
64 // Make a copy of the channel vector
65 std::vector<Ptr<LoraLogicalChannel>> vector;
66 vector.reserve(m_channelList.size());
67 std::copy(m_channelList.begin(), m_channelList.end(), std::back_inserter(vector));
68
69 return vector;
70}
71
72std::vector<Ptr<LoraLogicalChannel>>
74{
75 NS_LOG_FUNCTION(this);
76
77 // Make a copy of the channel vector
78 std::vector<Ptr<LoraLogicalChannel>> vector;
79 vector.reserve(m_channelList.size());
80 std::copy(m_channelList.begin(),
81 m_channelList.end(),
82 std::back_inserter(vector)); // Working on a copy
83
84 std::vector<Ptr<LoraLogicalChannel>> channels;
85 std::vector<Ptr<LoraLogicalChannel>>::iterator it;
86 for (it = vector.begin(); it != vector.end(); it++)
87 {
88 if ((*it)->IsEnabledForUplink())
89 {
90 channels.push_back(*it);
91 }
92 }
93
94 return channels;
95}
96
97Ptr<LoraSubBand>
99{
100 return GetLoraSubBandFromFrequency(channel->GetFrequency());
101}
102
103Ptr<LoraSubBand>
105{
106 NS_LOG_FUNCTION(this << frequency);
107 // Get the LoraSubBand this frequency belongs to
108 std::list<Ptr<LoraSubBand>>::iterator it;
109 for (it = m_subBandList.begin(); it != m_subBandList.end(); it++)
110 {
111 if ((*it)->BelongsToLoraSubBand(frequency))
112 {
113 return *it;
114 }
115 }
116
117 NS_LOG_ERROR("Requested frequency: " << frequency);
118 NS_ABORT_MSG("Warning: frequency is outside any known LoraSubBand.");
119
120 return 0; // If no LoraSubBand is found, return 0
121}
122
123void
125{
126 NS_LOG_FUNCTION(this << frequency);
127
128 // Create the new channel and increment the counter
129 Ptr<LoraLogicalChannel> channel = CreateObject<LoraLogicalChannel>(frequency);
130
131 // Add it to the list
132 m_channelList.push_back(channel);
133
134 NS_LOG_DEBUG("Added a channel. Current number of channels in list is " << m_channelList.size());
135}
136
137void
138LoraLogicalChannelHelper::AddChannel(Ptr<LoraLogicalChannel> logicalChannel)
139{
140 NS_LOG_FUNCTION(this << logicalChannel);
141
142 // Add it to the list
143 m_channelList.push_back(logicalChannel);
144}
145
146void
147LoraLogicalChannelHelper::SetChannel(uint8_t chIndex, Ptr<LoraLogicalChannel> logicalChannel)
148
149{
150 NS_LOG_FUNCTION(this << chIndex << logicalChannel);
151
152 m_channelList.at(chIndex) = logicalChannel;
153}
154
155void
157 double lastFrequency,
158 double dutyCycle,
159 double maxTxPowerDbm)
160{
161 NS_LOG_FUNCTION(this << firstFrequency << lastFrequency);
162
163 Ptr<LoraSubBand> subBand =
164 CreateObject<LoraSubBand>(firstFrequency, lastFrequency, dutyCycle, maxTxPowerDbm);
165
166 m_subBandList.push_back(subBand);
167}
168
169void
171{
172 NS_LOG_FUNCTION(this << subBand);
173
174 m_subBandList.push_back(subBand);
175}
176
177void
178LoraLogicalChannelHelper::RemoveChannel(Ptr<LoraLogicalChannel> logicalChannel)
179{
180 // Search and remove the channel from the list
181 std::vector<Ptr<LoraLogicalChannel>>::iterator it;
182 for (it = m_channelList.begin(); it != m_channelList.end(); it++)
183 {
184 Ptr<LoraLogicalChannel> currentChannel = *it;
185 if (currentChannel == logicalChannel)
186 {
187 m_channelList.erase(it);
188 return;
189 }
190 }
191}
192
193Time
195{
196 // Aggregate waiting time
197 Time aggregatedWaitingTime = m_nextAggregatedTransmissionTime - Simulator::Now();
198
199 // Handle case in which waiting time is negative
200 aggregatedWaitingTime = Seconds(std::max(aggregatedWaitingTime.GetSeconds(), double(0)));
201
202 NS_LOG_DEBUG("Aggregated waiting time: " << aggregatedWaitingTime.GetSeconds());
203
204 return aggregatedWaitingTime;
205}
206
207Time
208LoraLogicalChannelHelper::GetWaitingTime(Ptr<LoraLogicalChannel> channel)
209{
210 NS_LOG_FUNCTION(this << channel);
211
212 // LoraSubBand waiting time
213 Time subBandWaitingTime =
214 GetLoraSubBandFromChannel(channel)->GetNextTransmissionTime() - Simulator::Now();
215
216 // Handle case in which waiting time is negative
217 subBandWaitingTime = Seconds(std::max(subBandWaitingTime.GetSeconds(), double(0)));
218
219 NS_LOG_DEBUG("Waiting time: " << subBandWaitingTime.GetSeconds());
220
221 return subBandWaitingTime;
222}
223
224void
225LoraLogicalChannelHelper::AddEvent(Time duration, Ptr<LoraLogicalChannel> channel)
226{
227 NS_LOG_FUNCTION(this << duration << channel);
228
229 Ptr<LoraSubBand> subBand = GetLoraSubBandFromChannel(channel);
230
231 double dutyCycle = subBand->GetDutyCycle();
232 double timeOnAir = duration.GetSeconds();
233
234 // Computation of necessary waiting time on this sub-band
235 subBand->SetNextTransmissionTime(Simulator::Now() + Seconds(timeOnAir / dutyCycle - timeOnAir));
236
237 // Computation of necessary aggregate waiting time
239 Simulator::Now() + Seconds(timeOnAir / m_aggregatedDutyCycle - timeOnAir);
240
241 NS_LOG_DEBUG("Time on air: " << timeOnAir);
242 NS_LOG_DEBUG("m_aggregatedDutyCycle: " << m_aggregatedDutyCycle);
243 NS_LOG_DEBUG("Current time: " << Simulator::Now().GetSeconds());
244 NS_LOG_DEBUG("Next transmission on this sub-band allowed at time: "
245 << (subBand->GetNextTransmissionTime()).GetSeconds());
246 NS_LOG_DEBUG("Next aggregated transmission allowed at time "
247 << m_nextAggregatedTransmissionTime.GetSeconds());
248}
249
250double
251LoraLogicalChannelHelper::GetTxPowerForChannel(Ptr<LoraLogicalChannel> logicalChannel)
252{
253 NS_LOG_FUNCTION_NOARGS();
254
255 // Get the maxTxPowerDbm from the LoraSubBand this channel is in
256 std::list<Ptr<LoraSubBand>>::iterator it;
257 for (it = m_subBandList.begin(); it != m_subBandList.end(); it++)
258 {
259 // Check whether this channel is in this LoraSubBand
260 if ((*it)->BelongsToLoraSubBand(logicalChannel->GetFrequency()))
261 {
262 return (*it)->GetMaxTxPowerDbm();
263 }
264 }
265 NS_ABORT_MSG("Logical channel doesn't belong to a known LoraSubBand");
266
267 return 0;
268}
269
270void
272{
273 NS_LOG_FUNCTION(this << index);
274
275 m_channelList.at(index)->DisableForUplink();
276}
277} // namespace ns3
This class supports LorawanMac instances by managing a list of the logical channels that the device i...
Time GetWaitingTime(Ptr< LoraLogicalChannel > channel)
Get the time it is necessary to wait for before transmitting on a given channel.
Ptr< LoraSubBand > GetLoraSubBandFromChannel(Ptr< LoraLogicalChannel > channel)
Get the LoraSubBand a channel belongs to.
void RemoveChannel(Ptr< LoraLogicalChannel > channel)
Remove a channel.
std::vector< Ptr< LoraLogicalChannel > > m_channelList
A vector of the LoraLogicalChannels that are currently registered within this helper.
void AddLoraSubBand(double firstFrequency, double lastFrequency, double dutyCycle, double maxTxPowerDbm)
Add a new LoraSubBand to this helper.
std::list< Ptr< LoraSubBand > > m_subBandList
A list of the LoraSubBands that are currently registered within this helper.
Ptr< LoraSubBand > GetLoraSubBandFromFrequency(double frequency)
Get the LoraSubBand a frequency belongs to.
void AddEvent(Time duration, Ptr< LoraLogicalChannel > channel)
Register the transmission of a packet.
Time m_nextAggregatedTransmissionTime
The next time at which.
void SetChannel(uint8_t chIndex, Ptr< LoraLogicalChannel > logicalChannel)
Set a new channel at a fixed index.
void DisableChannel(int index)
Disable the channel at a specified index.
void AddChannel(double frequency)
Add a new channel to the list.
std::vector< Ptr< LoraLogicalChannel > > GetChannelList(void)
Get the list of LoraLogicalChannels currently registered on this helper.
Time GetAggregatedWaitingTime(void)
Get the time it is necessary to wait before transmitting again, according to the aggregate duty cycle...
std::vector< Ptr< LoraLogicalChannel > > GetEnabledChannelList(void)
Get the list of LoraLogicalChannels currently registered on this helper that have been enabled for Up...
double GetTxPowerForChannel(Ptr< LoraLogicalChannel > logicalChannel)
Returns the maximum transmission power [dBm] that is allowed on a channel.
double m_aggregatedDutyCycle
transmission will be possible according to the aggregated transmission timer
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.