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 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("LoraLogicalChannelHelper");
37 
38 NS_OBJECT_ENSURE_REGISTERED(LoraLogicalChannelHelper);
39 
40 TypeId
42 {
43  static TypeId tid = TypeId("ns3::LoraLogicalChannelHelper").SetParent<Object>();
44  return tid;
45 }
46 
48  : m_nextAggregatedTransmissionTime(Seconds(0)),
49  m_aggregatedDutyCycle(1)
50 {
51  NS_LOG_FUNCTION(this);
52 }
53 
55 {
56  NS_LOG_FUNCTION(this);
57 }
58 
59 std::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 
72 std::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 
97 Ptr<LoraSubBand>
99 {
100  return GetLoraSubBandFromFrequency(channel->GetFrequency());
101 }
102 
103 Ptr<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 
123 void
125 {
126  NS_LOG_FUNCTION(this << frequency);
127 
128  // Create the new channel and increment the counter
129  Ptr<LoraLogicalChannel> channel = Create<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 
137 void
138 LoraLogicalChannelHelper::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 
146 void
147 LoraLogicalChannelHelper::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 
155 void
157  double lastFrequency,
158  double dutyCycle,
159  double maxTxPowerDbm)
160 {
161  NS_LOG_FUNCTION(this << firstFrequency << lastFrequency);
162 
163  Ptr<LoraSubBand> subBand =
164  Create<LoraSubBand>(firstFrequency, lastFrequency, dutyCycle, maxTxPowerDbm);
165 
166  m_subBandList.push_back(subBand);
167 }
168 
169 void
171 {
172  NS_LOG_FUNCTION(this << subBand);
173 
174  m_subBandList.push_back(subBand);
175 }
176 
177 void
178 LoraLogicalChannelHelper::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 
193 Time
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 
207 Time
208 LoraLogicalChannelHelper::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 
224 void
225 LoraLogicalChannelHelper::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 
250 double
251 LoraLogicalChannelHelper::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 
270 void
272 {
273  NS_LOG_FUNCTION(this << index);
274 
275  m_channelList.at(index)->DisableForUplink();
276 }
277 } // 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.