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 namespace ns3
29 {
30 
31 NS_LOG_COMPONENT_DEFINE("LoraLogicalChannelHelper");
32 
33 NS_OBJECT_ENSURE_REGISTERED(LoraLogicalChannelHelper);
34 
35 TypeId
37 {
38  static TypeId tid = TypeId("ns3::LoraLogicalChannelHelper").SetParent<Object>();
39  return tid;
40 }
41 
43  : m_nextAggregatedTransmissionTime(Seconds(0)),
44  m_aggregatedDutyCycle(1)
45 {
46  NS_LOG_FUNCTION(this);
47 }
48 
50 {
51  NS_LOG_FUNCTION(this);
52 }
53 
54 std::vector<Ptr<LoraLogicalChannel>>
56 {
57  NS_LOG_FUNCTION(this);
58 
59  // Make a copy of the channel vector
60  std::vector<Ptr<LoraLogicalChannel>> vector;
61  vector.reserve(m_channelList.size());
62  std::copy(m_channelList.begin(), m_channelList.end(), std::back_inserter(vector));
63 
64  return vector;
65 }
66 
67 std::vector<Ptr<LoraLogicalChannel>>
69 {
70  NS_LOG_FUNCTION(this);
71 
72  // Make a copy of the channel vector
73  std::vector<Ptr<LoraLogicalChannel>> vector;
74  vector.reserve(m_channelList.size());
75  std::copy(m_channelList.begin(),
76  m_channelList.end(),
77  std::back_inserter(vector)); // Working on a copy
78 
79  std::vector<Ptr<LoraLogicalChannel>> channels;
80  std::vector<Ptr<LoraLogicalChannel>>::iterator it;
81  for (it = vector.begin(); it != vector.end(); it++)
82  {
83  if ((*it)->IsEnabledForUplink())
84  {
85  channels.push_back(*it);
86  }
87  }
88 
89  return channels;
90 }
91 
92 Ptr<LoraSubBand>
94 {
95  return GetLoraSubBandFromFrequency(channel->GetFrequency());
96 }
97 
98 Ptr<LoraSubBand>
100 {
101  NS_LOG_FUNCTION(this << frequency);
102  // Get the LoraSubBand this frequency belongs to
103  std::list<Ptr<LoraSubBand>>::iterator it;
104  for (it = m_subBandList.begin(); it != m_subBandList.end(); it++)
105  {
106  if ((*it)->BelongsToLoraSubBand(frequency))
107  {
108  return *it;
109  }
110  }
111 
112  NS_LOG_ERROR("Requested frequency: " << frequency);
113  NS_ABORT_MSG("Warning: frequency is outside any known LoraSubBand.");
114 
115  return 0; // If no LoraSubBand is found, return 0
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION(this << frequency);
122 
123  // Create the new channel and increment the counter
124  Ptr<LoraLogicalChannel> channel = Create<LoraLogicalChannel>(frequency);
125 
126  // Add it to the list
127  m_channelList.push_back(channel);
128 
129  NS_LOG_DEBUG("Added a channel. Current number of channels in list is " << m_channelList.size());
130 }
131 
132 void
133 LoraLogicalChannelHelper::AddChannel(Ptr<LoraLogicalChannel> logicalChannel)
134 {
135  NS_LOG_FUNCTION(this << logicalChannel);
136 
137  // Add it to the list
138  m_channelList.push_back(logicalChannel);
139 }
140 
141 void
142 LoraLogicalChannelHelper::SetChannel(uint8_t chIndex, Ptr<LoraLogicalChannel> logicalChannel)
143 
144 {
145  NS_LOG_FUNCTION(this << chIndex << logicalChannel);
146 
147  m_channelList.at(chIndex) = logicalChannel;
148 }
149 
150 void
152  double lastFrequency,
153  double dutyCycle,
154  double maxTxPowerDbm)
155 {
156  NS_LOG_FUNCTION(this << firstFrequency << lastFrequency);
157 
158  Ptr<LoraSubBand> subBand =
159  Create<LoraSubBand>(firstFrequency, lastFrequency, dutyCycle, maxTxPowerDbm);
160 
161  m_subBandList.push_back(subBand);
162 }
163 
164 void
166 {
167  NS_LOG_FUNCTION(this << subBand);
168 
169  m_subBandList.push_back(subBand);
170 }
171 
172 void
173 LoraLogicalChannelHelper::RemoveChannel(Ptr<LoraLogicalChannel> logicalChannel)
174 {
175  // Search and remove the channel from the list
176  std::vector<Ptr<LoraLogicalChannel>>::iterator it;
177  for (it = m_channelList.begin(); it != m_channelList.end(); it++)
178  {
179  Ptr<LoraLogicalChannel> currentChannel = *it;
180  if (currentChannel == logicalChannel)
181  {
182  m_channelList.erase(it);
183  return;
184  }
185  }
186 }
187 
188 Time
190 {
191  // Aggregate waiting time
192  Time aggregatedWaitingTime = m_nextAggregatedTransmissionTime - Simulator::Now();
193 
194  // Handle case in which waiting time is negative
195  aggregatedWaitingTime = Seconds(std::max(aggregatedWaitingTime.GetSeconds(), double(0)));
196 
197  NS_LOG_DEBUG("Aggregated waiting time: " << aggregatedWaitingTime.GetSeconds());
198 
199  return aggregatedWaitingTime;
200 }
201 
202 Time
203 LoraLogicalChannelHelper::GetWaitingTime(Ptr<LoraLogicalChannel> channel)
204 {
205  NS_LOG_FUNCTION(this << channel);
206 
207  // LoraSubBand waiting time
208  Time subBandWaitingTime =
209  GetLoraSubBandFromChannel(channel)->GetNextTransmissionTime() - Simulator::Now();
210 
211  // Handle case in which waiting time is negative
212  subBandWaitingTime = Seconds(std::max(subBandWaitingTime.GetSeconds(), double(0)));
213 
214  NS_LOG_DEBUG("Waiting time: " << subBandWaitingTime.GetSeconds());
215 
216  return subBandWaitingTime;
217 }
218 
219 void
220 LoraLogicalChannelHelper::AddEvent(Time duration, Ptr<LoraLogicalChannel> channel)
221 {
222  NS_LOG_FUNCTION(this << duration << channel);
223 
224  Ptr<LoraSubBand> subBand = GetLoraSubBandFromChannel(channel);
225 
226  double dutyCycle = subBand->GetDutyCycle();
227  double timeOnAir = duration.GetSeconds();
228 
229  // Computation of necessary waiting time on this sub-band
230  subBand->SetNextTransmissionTime(Simulator::Now() + Seconds(timeOnAir / dutyCycle - timeOnAir));
231 
232  // Computation of necessary aggregate waiting time
234  Simulator::Now() + Seconds(timeOnAir / m_aggregatedDutyCycle - timeOnAir);
235 
236  NS_LOG_DEBUG("Time on air: " << timeOnAir);
237  NS_LOG_DEBUG("m_aggregatedDutyCycle: " << m_aggregatedDutyCycle);
238  NS_LOG_DEBUG("Current time: " << Simulator::Now().GetSeconds());
239  NS_LOG_DEBUG("Next transmission on this sub-band allowed at time: "
240  << (subBand->GetNextTransmissionTime()).GetSeconds());
241  NS_LOG_DEBUG("Next aggregated transmission allowed at time "
242  << m_nextAggregatedTransmissionTime.GetSeconds());
243 }
244 
245 double
246 LoraLogicalChannelHelper::GetTxPowerForChannel(Ptr<LoraLogicalChannel> logicalChannel)
247 {
248  NS_LOG_FUNCTION_NOARGS();
249 
250  // Get the maxTxPowerDbm from the LoraSubBand this channel is in
251  std::list<Ptr<LoraSubBand>>::iterator it;
252  for (it = m_subBandList.begin(); it != m_subBandList.end(); it++)
253  {
254  // Check whether this channel is in this LoraSubBand
255  if ((*it)->BelongsToLoraSubBand(logicalChannel->GetFrequency()))
256  {
257  return (*it)->GetMaxTxPowerDbm();
258  }
259  }
260  NS_ABORT_MSG("Logical channel doesn't belong to a known LoraSubBand");
261 
262  return 0;
263 }
264 
265 void
267 {
268  NS_LOG_FUNCTION(this << index);
269 
270  m_channelList.at(index)->DisableForUplink();
271 }
272 } // namespace ns3
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.